package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.*;
import com.sc.nft.dto.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.EcologyHatchCountDTO;
import com.sc.nft.entity.dto.SaasTaskBurialPointDTO;
import com.sc.nft.entity.vo.*;
import com.sc.nft.entity.vo.ecology.*;
import com.sc.nft.enums.*;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.helper.MessageQueueHelper;
import com.sc.nft.service.*;
import com.sc.nft.util.BigDecimalUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Service
public class EcologySmeltingImpl implements EcologySmeltingService {

    private final UserEcologyPointsService userEcologyPointsService;
    private final UserEcologyHatchRecordsDao userEcologyHatchRecordsDao;
    private final StaticDataDao staticDataDao;
    private final EcologyHatchConfDao ecologyHatchConfDao;
    private final UserCreatorInfoDao userCreatorInfoDao;
    private final DigitalCollectionDao digitalCollectionDao;
    private final EcologyHatchRewardsConfDao ecologyHatchRewardsConfDao;
    private final UserCollectionDao userCollectionDao;
    private final UserCollectionService userCollectionService;
    private final UserEcologyHatchRewardsRecordsDao userEcologyHatchRewardsRecordsDao;
    private final UserInfoDao userInfoDao;
    private final UserEcologyPointsDao userEcologyPointsDao;
    private final UserEcologyPointsQuotaRecordsDao userEcologyPointsQuotaRecordsDao;
    private final MessageQueueHelper messageQueueHelper;
    private final UserEcologyPointsQuotaLogDao userEcologyPointsQuotaLogDao;
    private final EcologyHatchCollecionShareProfitConfDao ecologyHatchCollecionShareProfitConfDao;
    private final EcologyHatchShareProfitDao ecologyHatchShareProfitDao;
    private final DaoEcologyPointsService daoEcologyPointsService;
    private final UserEcologyUsableAmountUpperLimitDetailDao UserEcologyUsableAmountUpperLimitDetaildao;
    private final UserEcologyCastUpperLimitService userEcologyCastUpperLimitService;
    private final EcologyHatchMethodConfService ecologyHatchMethodConfService;
    private final EcologyHatchMethodCollectionConfService ecologyHatchMethodCollectionConfService;
    private final UserEcologyReforgeUpperLimitService userEcologyReforgeUpperLimitService;
    private final UserEcologyCollectionRecordsDao userEcologyCollectionRecordsDao;
    private final EcologyHatchShareProfitMethodConfDao ecologyHatchShareProfitMethodConfDao;
    private final UserCityServerCentreDao userCityServerCentreDao;
    private final MarketManagementDaoPoolService marketManagementDaoPoolService;
    private final UserEcologyHatchUpperLimitDao userEcologyHatchUpperLimitDao;
    private final UserEcologyHatchUpperLimitService userEcologyHatchUpperLimitService;
    private final UserConsensusService userConsensusService;
    private final ExitConsensusUserDao exitConsensusUserDao;
    private final EcologyHatchRatioDao ecologyHatchRatioDao;
    private final EcologyHatchExtraRewardsDao ecologyHatchExtraRewardsDao;
    private final EcologyHatchExtraRewardsConfigDao ecologyHatchExtraRewardsConfigDao;
    private final RedisTemplate redisTemplate;
    private final EcologyHatchExtraRewardsMethodConfDao ecologyHatchExtraRewardsMethodConfDao;
    private final EcologyCollectionShareProfitConfDao ecologyCollectionShareProfitConfDao;
    private final EcologyShareProfitServiceCenterConfDao ecologyShareProfitServiceCenterConfDao;
    private final NewEcologyHatchShareProfitDao newEcologyHatchShareProfitDao;
    private final ShareProfitDaoPoolDao shareProfitDaoPoolDao;


    @Override
    public HatchHomeVO hatchHome(UserInfo user) {
        HatchHomeVO hatchHomeVO = new HatchHomeVO();
        //用户生态积分(燃料)
        UserEcologyPoints userEcologyPoints = userEcologyPointsService.getOneByUserId(user.getId());
        hatchHomeVO.setUserEcologyPoints(ObjectUtil.isNull(userEcologyPoints) ? BigDecimal.ZERO : userEcologyPoints.getAmount());

        //查询用户历史记录的消耗总和
        hatchHomeVO.setExpendEcologyPoints(userEcologyHatchRecordsDao.getSumEcologyPointsByUserId(user.getId()));

        hatchHomeVO.setSmeltingPoolImage(staticDataDao.getByType("smelting_pool_image").getValue());
        hatchHomeVO.setSmeltingEquityImage(staticDataDao.getByType("smelting_equity_image").getValue());
        hatchHomeVO.setSmeltingRuleImage(staticDataDao.getByType("smelting_rule_image").getValue());
        hatchHomeVO.setEcologyPointsImage(staticDataDao.getByType("ecology_points_image").getValue());
        return hatchHomeVO;
    }

    @Override
    public Page<HatchPageVO> hatchPage(UserInfo user, Integer pageNo, Integer pageSize, Long userCreatorId) {
        if (pageSize == 20) {
            pageSize = 200;
        }
        List<HatchCountPageVO> hatchCountVO = new ArrayList<>();
        String key = "HATCH_COUNT";
        if (userCreatorId != null) {
            key = key + "_" + userCreatorId;
        }
        if (redisTemplate.hasKey(key)) {
            hatchCountVO = JSONObject.parseArray(redisTemplate.opsForValue().get(key).toString(), HatchCountPageVO.class);
        } else {
            hatchCountVO = userEcologyHatchRecordsDao.getHatchCountVO(userCreatorId);
            redisTemplate.opsForValue().set(key, JSONObject.toJSONString(hatchCountVO), 30, TimeUnit.SECONDS);
        }
        Map<Long, Integer> hatchCountVOMap = hatchCountVO.stream().collect(Collectors.toMap(HatchCountPageVO::getEcologyHatchId, HatchCountPageVO::getCount));
        Page<HatchPageVO> page = ecologyHatchConfDao.hatchPage(user.getId(), new Page(pageNo, pageSize), userCreatorId);
        for (HatchPageVO record : page.getRecords()) {
            DigitalCollection collection = digitalCollectionDao.getById(record.getCollectionId());
            UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(collection.getUserCreatorId());
            EcologyHatchConf byId = ecologyHatchConfDao.getById(record.getId());
            //获取已熔炼数量
            Integer hatchCount = hatchCountVOMap.get(record.getId());
            if (Objects.isNull(hatchCount)) {
                hatchCount = 0;
            }
            //熔炼总份数 - 已熔炼份数 = 剩余熔炼份数
            int ecologyHatchCount = byId.getTotalHatchCount() - hatchCount;
            if (0 >= ecologyHatchCount) {
                ecologyHatchCount = 0;
            }
            record.setEcologyHatchCount(ecologyHatchCount);
            record.setIsShowRemainder(byId.getIsShowRemainder());
            record.setDaoImage(userCreatorInfo.getCreatorAvatarImg());
            record.setDaoName(userCreatorInfo.getDaoName());
            List<HatchMethodVO> hatchMethodVOList = ecologyHatchMethodConfService.getHatchMethodVO(user.getId(), record.getId(), record);
            record.setHatchMethodVOList(hatchMethodVOList);
        }
        return page;
    }

    @Override
    public HatchRewardsSummaryVO preHatchRewards(Long id, Long methodId, Integer hatchCount, UserInfo user) {

        HatchRewardsSummaryVO hatchRewardsSummaryVO = new HatchRewardsSummaryVO();

        EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getById(id);
        Assert.notNull(ecologyHatchConf, () -> new GlobalRunTimeException("熔炼配置不存在"));
        Assert.isTrue(ecologyHatchConf.getStatus(), () -> new GlobalRunTimeException("熔炼配置已关闭"));
        Assert.isTrue(hatchCount <= ecologyHatchConf.getUpperLimit(), () -> new GlobalRunTimeException(StrUtil.format("单次熔炼上限为:{}", ecologyHatchConf.getUpperLimit())));

        //获取奖励
        List<EcologyHatchRewardsConf> rewardsConfList = ecologyHatchRewardsConfDao.getListByEcologyHatchId(id, methodId);


        ArrayList<EcologyHatchRewardsVO> totalList = Lists.newArrayList();
        ArrayList<EcologyHatchRewardsVO> rewardList = Lists.newArrayList();
        for (EcologyHatchRewardsConf ecologyHatchRewardsConf : rewardsConfList) {
            if (ecologyHatchRewardsConf.getRewardsType() == EcologyRewardsType.ECOLOGY_POINTS) {
                ecologyHatchRewardsConf.setLinkImage(staticDataDao.getByType("ecology_points_image").getValue());

            }


            EcologyHatchRewardsVO ecologyHatchRewardsVO = BeanUtil.copyProperties(ecologyHatchRewardsConf, EcologyHatchRewardsVO.class);
            ecologyHatchRewardsVO.setLinkCount(ecologyHatchRewardsConf.getLinkCount());
            rewardList.add(ecologyHatchRewardsVO);

            BigDecimal count = BigDecimal.ZERO;
            //周期除以奖励周期 = 奖励次数
            if (ecologyHatchRewardsConf.getRewardsType() == EcologyRewardsType.ECOLOGY_POINTS) {
                count = Convert.toBigDecimal(ecologyHatchConf.getHatchCycle()).divide
                        (Convert.toBigDecimal(ecologyHatchRewardsConf.getRewardsCycle()), 2, BigDecimal.ROUND_DOWN).stripTrailingZeros();
            } else if (ecologyHatchRewardsConf.getRewardsType() == EcologyRewardsType.EQUITY_PROPS) {
                count = Convert.toBigDecimal(ecologyHatchConf.getHatchCycle()).divide
                        (Convert.toBigDecimal(ecologyHatchRewardsConf.getRewardsCycle()), 0, BigDecimal.ROUND_DOWN).stripTrailingZeros();
            } else if (ecologyHatchRewardsConf.getRewardsType() == EcologyRewardsType.ECOLOGY_MARK) {
                count = Convert.toBigDecimal(ecologyHatchConf.getHatchCycle()).divide
                        (Convert.toBigDecimal(ecologyHatchRewardsConf.getRewardsCycle()), 0, BigDecimal.ROUND_DOWN).stripTrailingZeros();
            }


            //奖励数量 = 奖励数量 * 奖励次数
            BigDecimal multiply = Convert.toBigDecimal(ecologyHatchRewardsConf.getLinkCount()).multiply(count).multiply(Convert.toBigDecimal(hatchCount));

            EcologyHatchRewardsVO totalRewards = BeanUtil.copyProperties(ecologyHatchRewardsConf, EcologyHatchRewardsVO.class);
            totalRewards.setLinkCount(multiply);
            totalList.add(totalRewards);
        }
        hatchRewardsSummaryVO.setRewardlist(rewardList);
        hatchRewardsSummaryVO.setTotallist(totalList);
//
//        ArrayList<EcologyHatchRewardsVO> extraTotalList = Lists.newArrayList();
//        ArrayList<EcologyHatchRewardsVO> extraRewardList = Lists.newArrayList();
//        //查询是否有额外奖励
        EcologyHatchExtraRewards ecologyHatchExtraRewards = ecologyHatchExtraRewardsDao.getOpenByEcologyHatchId(id);
        if (Objects.nonNull(ecologyHatchExtraRewards)) {
            //fixme 额外奖励图片
            hatchRewardsSummaryVO.setExtraRuleRemarkImg(ecologyHatchExtraRewards.getExtraRuleRemarkImg());
        }
//        if (Objects.nonNull(ecologyHatchExtraRewards)) {
//            //查询配置
//            List<EcologyHatchExtraRewardsConfig> rewardsConfigList = ecologyHatchExtraRewardsConfigDao.listByExtraRewardsId(ecologyHatchExtraRewards.getId(),id);
//            if (!CollectionUtils.isEmpty(rewardsConfigList)) {
//                for (EcologyHatchExtraRewardsConfig extraRewardsConfig : rewardsConfigList) {
//                    if (extraRewardsConfig.getRewardsType() == EcologyRewardsType.ECOLOGY_POINTS) {
//                        extraRewardsConfig.setLinkImage(staticDataDao.getByType("ecology_points_image").getValue());
//
//                    }
//                    EcologyHatchRewardsVO ecologyHatchRewardsVO = BeanUtil.copyProperties(extraRewardsConfig, EcologyHatchRewardsVO.class);
//                    ecologyHatchRewardsVO.setLinkCount(extraRewardsConfig.getLinkCount());
//                    ecologyHatchRewardsVO.setRewardsCycle(extraRewardsConfig.getDeliveryCycle());
//                    extraRewardList.add(ecologyHatchRewardsVO);
//                }
//                //总奖励
//                Map<String, List<EcologyHatchRewardsVO>> groupMap = extraRewardList.stream().collect(Collectors.groupingBy(EcologyHatchRewardsVO::getLinkName));
//                for (String key : groupMap.keySet()) {
//                    List<EcologyHatchRewardsVO> ecologyHatchRewardsVOS = groupMap.get(key);
//                    EcologyHatchRewardsVO ecologyHatchRewardsVO = new EcologyHatchRewardsVO();
//                    BeanUtil.copyProperties(ecologyHatchRewardsVOS.get(0),ecologyHatchRewardsVO);
//                    //将ecologyHatchRewardsVOS中为String格式的LinkCount字段转BigDecimal并求和
//                    BigDecimal count = ecologyHatchRewardsVOS.stream().map(EcologyHatchRewardsVO::getLinkCount)
//                            .map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add).multiply(Convert.toBigDecimal(hatchCount));
//                    ecologyHatchRewardsVO.setLinkCount(count);
//                    extraTotalList.add(ecologyHatchRewardsVO);
//                }
//            }
//        }
//        hatchRewardsSummaryVO.setExtraRewardList(BeanUtil.copyToList(rewardList,EcologyHatchRewardsVO.class));
//        hatchRewardsSummaryVO.setExtraTotalList(BeanUtil.copyToList(totalList,EcologyHatchRewardsVO.class));
//        if (id.equals(40L)){
//            for (EcologyHatchRewardsVO ecologyHatchRewardsVO : extraRewardList) {
//                ecologyHatchRewardsVO.setLinkImage("https://cdn.gometa.com.cn/scnft/other/%E5%8D%A1%E7%89%8C%E9%81%93%E5%85%B7%E5%8D%A11(1).jpg");
//                ecologyHatchRewardsVO.setLinkName("神秘奖励");
//            }
//        }
//        hatchRewardsSummaryVO.setExtraRewardList(extraRewardList);
//        hatchRewardsSummaryVO.setExtraTotalList(extraTotalList);

        return hatchRewardsSummaryVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void hatch(Long id, Long methodId, Integer hatchCount, UserInfo user) {
        // 推荐首次熔炼
        Integer userSum = userEcologyHatchRecordsDao.getUserSum(user.getId(), 0L);
        EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getById(id);
        if (userSum == 0) {
            // 首次熔炼
            userConsensusService.adjustConsensusService(user.getRecommendUserId(), ecologyHatchConf.getCollectionId(), BigDecimal.ONE, UserConsensusTypeEnums.PUSH_FIRST_SMELT, null, null);
        }

        Assert.notNull(ecologyHatchConf, () -> new GlobalRunTimeException("熔炼配置不存在"));
        Assert.isTrue(ecologyHatchConf.getStatus(), () -> new GlobalRunTimeException("熔炼配置已下架"));
        // 获取已熔炼数量
        Integer hatchCountByEcologyHatchId = userEcologyHatchRecordsDao.getHatchCountByEcologyHatchId(ecologyHatchConf.getId());
        //熔炼总份数 - 已熔炼份数 = 剩余熔炼份数
        int ecologyHatchCount = ecologyHatchConf.getTotalHatchCount() - hatchCountByEcologyHatchId;
        if (0 >= ecologyHatchCount) {
            ecologyHatchCount = 0;
        }
        Assert.isTrue(ecologyHatchCount >= hatchCount && ecologyHatchCount > 0, () -> new GlobalRunTimeException("当前藏品平台剩余熔炼总份数不足"));
        Assert.isTrue(hatchCount <= ecologyHatchConf.getUpperLimit(), () -> new GlobalRunTimeException(StrUtil.format("单次熔炼上限为:{}", ecologyHatchConf.getUpperLimit())));
        //获取用户熔炼剩余次数
        EcologyHatchCountDTO userHatchCount = getUserHatchCount(user.getId(), id);
        Assert.isTrue(userHatchCount.getSumRemainingCount() >= hatchCount, () -> new GlobalRunTimeException(StrUtil.format("熔炼次数不足,剩余熔炼次数为:{}", userHatchCount.getSumRemainingCount())));
        //获取熔炼方式
        EcologyHatchMethodConf methodConf = ecologyHatchMethodConfService.getById(methodId);
        Assert.notNull(methodConf, () -> new GlobalRunTimeException("熔炼方式"));
        Assert.isTrue(methodConf.getStatus(), () -> new GlobalRunTimeException("熔炼方式未开启"));
        //获取熔炼方式藏品配置
        List<EcologyHatchMethodCollectionConf> collectionConfList = ecologyHatchMethodCollectionConfService.getList(methodId, id);
        List<Long> collectionIds = new ArrayList<>();
        // 熔炼消耗数量map
        Map<Long, Integer> collectionCountMap = new HashMap<>();
        // 熔炼销毁数量map
        Map<Long, Integer> collectionDestroyCountMap = new HashMap<>();
        // 用户需要消耗的藏品
        Map<Long, List<UserCollection>> collectionMap = new HashMap<>();
        // 所需藏品对应的藏品名称
        Map<Long, String> collectionNameMap = new HashMap<>();
        collectionNameMap.put(ecologyHatchConf.getCollectionId(), ecologyHatchConf.getCollectionName());
        // 需要消耗的藏品ID集合
        collectionIds.add(ecologyHatchConf.getCollectionId());
        // 消耗数量
        //所需数量 = 熔炼次数 * 消耗数量
        Integer total = 0;
        Integer count = 0;
        Integer mainExpendCount = 0;
//        Integer count = hatchCount * ecologyHatchConf.getExpendCount();
//        total = total + count;
//        collectionCountMap.put(ecologyHatchConf.getCollectionId(), count);
//        // 销毁数量
//        collectionDestroyCountMap.put(ecologyHatchConf.getCollectionId(), ecologyHatchConf.getDestroyCount() * hatchCount);

        for (EcologyHatchMethodCollectionConf ecologyHatchMethodCollectionConf : collectionConfList) {
            List<UserCollection> userCollections = userCollectionDao.getUserCollectionByCollectionIdAndLimit(user.getId(), ecologyHatchMethodCollectionConf.getCollectionId(), ecologyHatchMethodCollectionConf.getExpendCount());
            Assert.isTrue(userCollections.size() >= ecologyHatchMethodCollectionConf.getExpendCount(), () -> new GlobalRunTimeException(StrUtil.format("持有藏品{}不足", ecologyHatchConf.getCollectionName())));
            // 需要消耗的藏品ID集合
            if (!collectionIds.contains(ecologyHatchMethodCollectionConf.getCollectionId())) {
                collectionIds.add(ecologyHatchMethodCollectionConf.getCollectionId());
            }
            // 藏品名称
            if (Objects.isNull(collectionNameMap.get(ecologyHatchMethodCollectionConf.getCollectionId()))) {
                collectionNameMap.put(ecologyHatchMethodCollectionConf.getCollectionId(), ecologyHatchMethodCollectionConf.getCollectionName());
            }
            // 熔炼方式： 消耗数量 = 熔炼次数 * 消耗数量
            if (Objects.nonNull(collectionCountMap.get(ecologyHatchMethodCollectionConf.getCollectionId()))) {
                Integer num = collectionCountMap.get(ecologyHatchMethodCollectionConf.getCollectionId());
                collectionCountMap.put(ecologyHatchMethodCollectionConf.getCollectionId(), hatchCount * ecologyHatchMethodCollectionConf.getExpendCount() + num);
            } else {
                collectionCountMap.put(ecologyHatchMethodCollectionConf.getCollectionId(), hatchCount * ecologyHatchMethodCollectionConf.getExpendCount());
            }

            // 熔炼方式：销毁数量 = 熔炼次数 * 销毁数量
            if (Objects.nonNull(collectionDestroyCountMap.get(ecologyHatchMethodCollectionConf.getCollectionId()))) {
                Integer DestroyNum = collectionDestroyCountMap.get(ecologyHatchMethodCollectionConf.getCollectionId());
                collectionDestroyCountMap.put(ecologyHatchMethodCollectionConf.getCollectionId(), hatchCount * ecologyHatchMethodCollectionConf.getDestroyCount() + DestroyNum);
            } else {
                collectionDestroyCountMap.put(ecologyHatchMethodCollectionConf.getCollectionId(), ecologyHatchMethodCollectionConf.getDestroyCount() * hatchCount);
            }
            //如果是主藏品
            if (ecologyHatchMethodCollectionConf.getIsMain()) {
                mainExpendCount = ecologyHatchMethodCollectionConf.getExpendCount();
                count = hatchCount * ecologyHatchMethodCollectionConf.getExpendCount();
                total = count;
            }
//            total = total + hatchCount * ecologyHatchMethodCollectionConf.getExpendCount();
        }

        // 根据消耗的数量，获取用户的藏品
        for (Long collectionId : collectionCountMap.keySet()) {
            Integer num = collectionCountMap.get(collectionId);
            List<UserCollection> userCollections = userCollectionDao.getUserCollectionByCollectionIdAndLimit(user.getId(), collectionId, num);
            Assert.isTrue(userCollections.size() >= num, () -> new GlobalRunTimeException(StrUtil.format("持有藏品{}不足", collectionNameMap.get(collectionId))));
            // 熔炼方式：用户需要消耗的藏品
            collectionMap.put(collectionId, userCollections);
        }

        UserEcologyHatchRecords userEcologyHatchRecords = new UserEcologyHatchRecords();
        userEcologyHatchRecords.setUserId(user.getId());
        userEcologyHatchRecords.setEcologyHatchId(ecologyHatchConf.getId());
        userEcologyHatchRecords.setMethodId(methodId);
        userEcologyHatchRecords.setRecommendUserId(user.getRecommendUserId());
        userEcologyHatchRecords.setCollectionId(ecologyHatchConf.getCollectionId());
        userEcologyHatchRecords.setCollectionName(ecologyHatchConf.getCollectionName());
        userEcologyHatchRecords.setHatchCycle(ecologyHatchConf.getHatchCycle());
        userEcologyHatchRecords.setAlreadyDay(0);
        userEcologyHatchRecords.setUseCount(count);
        userEcologyHatchRecords.setDaoId(ecologyHatchConf.getDaoId());
        userEcologyHatchRecords.setHatchCount(hatchCount);
        userEcologyHatchRecords.setDynamicRewardAmount(methodConf.getDynamicRewardAmount());
//        DigitalCollection collection = digitalCollectionDao.getById(ecologyHatchConf.getCollectionId());
        List<DigitalCollection> digitalCollectionList = digitalCollectionDao.getByIds(collectionIds);
        BigDecimal realEcologyPoints = BigDecimal.ZERO;
        // 熔炼的藏品
        DigitalCollection collection = null;
        for (DigitalCollection digitalCollection : digitalCollectionList) {
            realEcologyPoints = realEcologyPoints.add(digitalCollection.getIssuePrice().multiply(Convert.toBigDecimal(collectionCountMap.get(digitalCollection.getId()))));
            if (ecologyHatchConf.getCollectionId().equals(digitalCollection.getId())) {
                collection = digitalCollection;
            }
        }
        Assert.notNull(collection, () -> new GlobalRunTimeException("熔炼藏品不存在"));

        //发行价 * 数量
        userEcologyHatchRecords.setEcologyPoints(collection.getIssuePrice().multiply(Convert.toBigDecimal(count)));
        userEcologyHatchRecords.setRealEcologyPoints(realEcologyPoints);
        userEcologyHatchRecords.setCollectionImage(collection.getCreationContent());
        userEcologyHatchRecords.setStatus(UserEcologyHatchRecordsStatus.UNDER_WAY);

        userEcologyHatchRecords.setIsSettleDirectThrustIncome(EcologyHatchDirectThrustIncomeType.NOT_FOUND_RECOMMEND);
        userEcologyHatchRecords.setIsSettleTeamIncome(Boolean.TRUE);
        userEcologyHatchRecords.insert();

        // 添加熔炼奖励快照
        List<EcologyHatchRewardsConf> rewardsConfList = ecologyHatchRewardsConfDao.getListByEcologyHatchId(id, methodId);
        List<EcologyHatchRecordsRewards> ecologyHatchRecordsRewardsList = BeanUtil.copyToList(rewardsConfList, EcologyHatchRecordsRewards.class);
        for (EcologyHatchRecordsRewards ecologyHatchRecordsRewards : ecologyHatchRecordsRewardsList) {
            ecologyHatchRecordsRewards.setUserEcologyHatchRecordsId(userEcologyHatchRecords.getId());
            ecologyHatchRecordsRewards.setExtraReward(Boolean.FALSE);
            ecologyHatchRecordsRewards.insert();
        }
        //查询是否有额外奖励
        EcologyHatchExtraRewards ecologyHatchExtraRewards = ecologyHatchExtraRewardsDao.getOpenByEcologyHatchId(id);
        if (Objects.nonNull(ecologyHatchExtraRewards)) {
            //查询额外奖励的配置
            List<EcologyHatchExtraRewardsMethodConf> extraRewardsMethodConfList = ecologyHatchExtraRewardsMethodConfDao.listByExtraRewardsId(ecologyHatchExtraRewards.getId());
            if (!CollectionUtils.isEmpty(extraRewardsMethodConfList)) {
                Long extraMethodId = 0L;
                if (extraRewardsMethodConfList.size() == 1) {
                    extraMethodId = extraRewardsMethodConfList.get(0).getId();
                } else {
                    Map<Long, BigDecimal> probabilityMap = extraRewardsMethodConfList.stream().collect(Collectors.toMap(EcologyHatchExtraRewardsMethodConf::getId, EcologyHatchExtraRewardsMethodConf::getProbability));
                    extraMethodId = getRandomValue(probabilityMap);
                }
                //查询配置
                List<EcologyHatchExtraRewardsConfig> rewardsConfigList = ecologyHatchExtraRewardsConfigDao.listByMethodId(ecologyHatchExtraRewards.getId(), extraMethodId);
                if (!CollectionUtils.isEmpty(rewardsConfigList)) {
//                List<EcologyHatchRecordsRewards> extraEcologyHatchRecordsRewardsList = new ArrayList<>();
                    for (EcologyHatchExtraRewardsConfig extraRewardsConfig : rewardsConfigList) {
                        EcologyHatchRecordsRewards recordsRewards = new EcologyHatchRecordsRewards();
                        BeanUtil.copyProperties(extraRewardsConfig, recordsRewards);
                        recordsRewards.setUserEcologyHatchRecordsId(userEcologyHatchRecords.getId());
                        recordsRewards.setMethodId(0L);
                        recordsRewards.setRewardsCycle(extraRewardsConfig.getDeliveryCycle());
                        recordsRewards.setExtraReward(Boolean.TRUE);
                        recordsRewards.insert();
                    }
                }
            }

        }

        //用户积分上限日志表
        UserEcologyPointsQuotaLog userEcologyPointsQuotaLog = new UserEcologyPointsQuotaLog();
        userEcologyPointsQuotaLog.setDaoId(collection.getUserCreatorId());

//        UserEcologyPoints userEcologyPoints = userEcologyPointsDao.getOneByUserId(user.getId());

        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(collection.getUserCreatorId());
        userEcologyPointsQuotaLog.setDaoName(userCreatorInfo.getDaoName());
        userEcologyPointsQuotaLog.setUserId(user.getId());
        userEcologyPointsQuotaLog.setCollectionId(collection.getId());
        userEcologyPointsQuotaLog.setCollectionName(collection.getFirstTitle());
        userEcologyPointsQuotaLog.setUsePoints(userEcologyHatchRecords.getEcologyPoints());


        StaticData staticData = staticDataDao.getByType("ecology_release_multiple");
        BigDecimal ecologyReleaseMultiple = ObjectUtil.isNull(staticData) ? Convert.toBigDecimal(3) : Convert.toBigDecimal(staticData.getValue());
        BigDecimal pointsQuota = userEcologyHatchRecords.getRealEcologyPoints().multiply(ecologyReleaseMultiple).setScale(2, BigDecimal.ROUND_DOWN);
        userEcologyPointsQuotaLog.setPointsQuota(pointsQuota);


        UserEcologyPointsQuotaLog lastOneUserEcologyPointsQuotaLog = userEcologyPointsQuotaLogDao.getLastOneByUserId(user.getId());
        BigDecimal beforePoints = ObjectUtil.isNull(lastOneUserEcologyPointsQuotaLog) ? BigDecimal.ZERO : lastOneUserEcologyPointsQuotaLog.getAfterPoints();
        userEcologyPointsQuotaLog.setBeforePoints(beforePoints);
        userEcologyPointsQuotaLog.setAfterPoints(beforePoints.add(pointsQuota));
        userEcologyPointsQuotaLog.setIsAdd(Boolean.TRUE);
        userEcologyPointsQuotaLog.setRemark(StrUtil.EMPTY);
        userEcologyPointsQuotaLog.insert();

        UserEcologyPoints userEcologyPoints = userEcologyPointsDao.getOneByUserId(user.getId());
        UserEcologyUsableAmountUpperLimitDetail userEcologyUsableAmountUpperLimitDetail = new UserEcologyUsableAmountUpperLimitDetail();
        userEcologyUsableAmountUpperLimitDetail.setUserId(user.getId());
        userEcologyUsableAmountUpperLimitDetail.setType(UserEcologyUsableAmountUpperLimitDetailTypeEnum.SMELTING);
        userEcologyUsableAmountUpperLimitDetail.setTypeName(StrUtil.format("{}:{}", UserEcologyUsableAmountUpperLimitDetailTypeEnum.SMELTING.getDescription(), ecologyHatchConf.getCollectionName()));
        userEcologyUsableAmountUpperLimitDetail.setAmount(pointsQuota);
        userEcologyUsableAmountUpperLimitDetail.setBeforeBalance(userEcologyPoints.getUsableAmountUpperLimit());
        userEcologyUsableAmountUpperLimitDetail.setAfterBalance(userEcologyPoints.getUsableAmountUpperLimit().add(pointsQuota));
        userEcologyUsableAmountUpperLimitDetail.setIsAdd(UserEcologyUsableAmountUpperLimitDetailTypeEnum.SMELTING.getIsAdd());
        userEcologyUsableAmountUpperLimitDetail.insert();

        //维护用户生态积分上限
        Assert.isTrue(userEcologyPointsDao.addUsableAmountUpperLimitByUserId(user.getId(), pointsQuota), () -> new GlobalRunTimeException("系统繁忙,请稍后重试"));


        // 记录熔炼时需要消耗的藏品数量
        for (Long collectionId : collectionCountMap.keySet()) {
            UserEcologyCollectionRecords userEcologyCollectionRecords = new UserEcologyCollectionRecords();
            userEcologyCollectionRecords.setUserId(user.getId());
            userEcologyCollectionRecords.setUserEcologyHatchRecordsId(userEcologyHatchRecords.getId());
            userEcologyCollectionRecords.setEcologyHatchId(ecologyHatchConf.getId());
            userEcologyCollectionRecords.setCollectionId(collectionId);
            userEcologyCollectionRecords.setCollectionCount(collectionCountMap.get(collectionId));
            userEcologyCollectionRecords.insert();
        }

        // 需要减少的共识度
        BigDecimal needSubConsensusDegree = BigDecimalUtils.multiplys(hatchCount, mainExpendCount);

        ExitConsensusUser exitConsensusUser = exitConsensusUserDao.getByUserId(user.getId());
        Boolean isConsensus = ObjectUtil.isNull(exitConsensusUser) || !exitConsensusUser.getStatus();
        if (isConsensus) {
            if (ecologyHatchConf.getConsumptionConsensus()) {
                for (Long collectionId : collectionCountMap.keySet()) {
                    Integer num = collectionCountMap.get(collectionId);
                    userConsensusService.adjustConsensusService(user.getId(), collectionId, BigDecimal.valueOf(num).negate(), UserConsensusTypeEnums.SMELT, ecologyHatchConf.getCollectionName(), null);
                }
            } else {
                userConsensusService.adjustConsensusService(user.getId(), ecologyHatchConf.getCollectionId(), needSubConsensusDegree.negate(), UserConsensusTypeEnums.SMELT, ecologyHatchConf.getCollectionName(), null);
            }
        }
        //回收藏品的集合
        List<UserCollection> recycleList = Lists.newArrayList();
        //销毁藏品的集合
        List<UserCollection> destroyList = Lists.newArrayList();
        for (Long collectionId : collectionMap.keySet()) {
            List<UserCollection> userCollections = collectionMap.get(collectionId);
            Integer destroyCount = collectionDestroyCountMap.get(collectionId);
            if (destroyCount > 0) {
                destroyList.addAll(ListUtil.sub(userCollections, 0, destroyCount));
                recycleList.addAll(ListUtil.sub(userCollections, destroyCount, userCollections.size()));
            } else {
                recycleList.addAll(userCollections);
            }
        }

        //熔炼之后  增加铸造上限
        userEcologyCastUpperLimitService.addCountByUserIdAndCollectionId(user.getId(), ecologyHatchConf.getCollectionId(), ecologyHatchConf.getAddCastCount() * hatchCount, UserEcologyCastUpperLimitDetailsTypeEnum.SMELTING, ecologyHatchConf.getCollectionName(), userEcologyHatchRecords.getId());
        // 增加重铸造上限
        userEcologyReforgeUpperLimitService.addCountByUserIdAndCollectionId(user.getId(), ecologyHatchConf.getCollectionId(), ecologyHatchConf.getAddReforgeCount() * hatchCount, UserEcologyReforgeUpperLimitDetailsTypeEnum.SMELTING, ecologyHatchConf.getCollectionName(), userEcologyHatchRecords.getId());

        int beforeCount = userHatchCount.getSumRemainingCount();

        // 如果初始熔炼有份数，但不足传入的熔炼份数，先减初始熔炼份数，再减可消耗熔炼份数
        if (hatchCount > userHatchCount.getRemainingHatchCount()) {
            int hatchCount_ = hatchCount - userHatchCount.getRemainingHatchCount();
            userEcologyHatchUpperLimitService.subUpperLimitCountByUserIdAndCollectionId(user.getId(), ecologyHatchConf.getCollectionId(), hatchCount_,
                    UserEcologyHatchUpperLimitDetailsTypeEnum.SMELTING, ecologyHatchConf.getCollectionName(), userEcologyHatchRecords.getId(), beforeCount, hatchCount);
            // 当初始熔炼上限不足，且有可消耗熔炼份数剩余份数时
        }/*else if (userHatchCount.getRemainingHatchCount() == 0){
            //熔炼后 减少熔炼可消耗份数
            userEcologyHatchUpperLimitService.subUpperLimitCountByUserIdAndCollectionId(user.getId(), ecologyHatchConf.getCollectionId(),hatchCount,
                    UserEcologyHatchUpperLimitDetailsTypeEnum.SMELTING,ecologyHatchConf.getCollectionName(),userEcologyHatchRecords.getId(),beforeCount,hatchCount);
        }*/ else {
            userEcologyHatchUpperLimitService.addUserEcologyHatchUpperLimitDetails(user.getId(), ecologyHatchConf.getCollectionId(), hatchCount, UserEcologyHatchUpperLimitDetailsTypeEnum.SMELTING,
                    ecologyHatchConf.getCollectionName(), userEcologyHatchRecords.getId(), beforeCount);
        }

        //回收记录
        for (UserCollection userCollection : recycleList) {
            UserEcologyHatchCollectionRecords userEcologyHatchCollectionRecords = new UserEcologyHatchCollectionRecords();
            userEcologyHatchCollectionRecords.setUserId(userCollection.getUserId());
            userEcologyHatchCollectionRecords.setUserCollectionId(userCollection.getId());
            userEcologyHatchCollectionRecords.setEcologyHatchId(ecologyHatchConf.getId());
            userEcologyHatchCollectionRecords.setUserEcologyHatchRecordsId(userEcologyHatchRecords.getId());
            userEcologyHatchCollectionRecords.setCollectionId(userCollection.getCollectionId());
            userEcologyHatchCollectionRecords.setCollectionName(userCollection.getFirstTitle());
            userEcologyHatchCollectionRecords.setCollectionImage(userCollection.getCollectionImage());
            userEcologyHatchCollectionRecords.setNumbering(String.valueOf(userCollection.getNumbering()));
            userEcologyHatchCollectionRecords.setOldType(userCollection.getType());
            userEcologyHatchCollectionRecords.setBuyPrice(userCollection.getBuyPrice());
            userEcologyHatchCollectionRecords.setType(UserEcologyHatchCollectionTypeRecordsEnum.RECYCLE);
            userEcologyHatchCollectionRecords.insert();
        }
        //回收
        userCollectionService.recoverCollections(recycleList);

        for (UserCollection userCollection : destroyList) {
            UserEcologyHatchCollectionRecords userEcologyHatchCollectionRecords = new UserEcologyHatchCollectionRecords();
            userEcologyHatchCollectionRecords.setUserId(userCollection.getUserId());
            userEcologyHatchCollectionRecords.setUserCollectionId(userCollection.getId());
            userEcologyHatchCollectionRecords.setEcologyHatchId(ecologyHatchConf.getId());
            userEcologyHatchCollectionRecords.setUserEcologyHatchRecordsId(userEcologyHatchRecords.getId());
            userEcologyHatchCollectionRecords.setCollectionId(userCollection.getCollectionId());
            userEcologyHatchCollectionRecords.setCollectionName(userCollection.getFirstTitle());
            userEcologyHatchCollectionRecords.setCollectionImage(userCollection.getCollectionImage());
            userEcologyHatchCollectionRecords.setNumbering(String.valueOf(userCollection.getNumbering()));
            userEcologyHatchCollectionRecords.setOldType(userCollection.getType());
            userEcologyHatchCollectionRecords.setBuyPrice(userCollection.getBuyPrice());
            userEcologyHatchCollectionRecords.setType(UserEcologyHatchCollectionTypeRecordsEnum.DESTROY);
            userEcologyHatchCollectionRecords.insert();
        }
        //销毁
        userCollectionService.ecologyDestroyCollections(destroyList);
        //平台和DAO分成处理
        messageQueueHelper.sendMessage(MessageTopic.ECOLOGY_HATCH_DIVIDE_INTO_TOPIC, userEcologyHatchRecords);
        // 熔炼记录预计奖励初始化
        messageQueueHelper.sendMessage(MessageTopic.PERIODIC_REWARD_INITIALIZATION, userEcologyHatchRecords.getId());

        // 全都完事以后发送埋点数据
        Integer finalTotal = total;
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                SaasTaskBurialPointDTO saasTaskBurialPointDTO = new SaasTaskBurialPointDTO();
                messageQueueHelper.sendMessage(MessageTopic.DISK_TAKER, saasTaskBurialPointDTO.wallet(user.getId(),
                                SaasTaskTypeEnum.SMELTING_COLLECTION, Convert.toBigDecimal(finalTotal), 1,
                                ecologyHatchConf.getCollectionId()), SaasTaskTypeEnum.SMELTING_COLLECTION.name(),
                        StrUtil.format("{}:{}:{}", user.getId(), userEcologyHatchRecords.getId().toString(), SaasTaskTypeEnum.SMELTING_COLLECTION.name()));

                messageQueueHelper.sendMessage(MessageTopic.DISK_TAKER, saasTaskBurialPointDTO.wallet(user.getId(),
                                SaasTaskTypeEnum.SMELTING_APPOINT_COLLECTION, Convert.toBigDecimal(hatchCount),
                                1, ecologyHatchConf.getCollectionId(), userEcologyHatchRecords.getId()),
                        SaasTaskTypeEnum.SMELTING_APPOINT_COLLECTION.name(),
                        StrUtil.format("{}:{}:{}", user.getId(), userEcologyHatchRecords.getId().toString(), SaasTaskTypeEnum.SMELTING_APPOINT_COLLECTION.name()));

                messageQueueHelper.sendMessage(MessageTopic.DISK_TAKER, saasTaskBurialPointDTO.wallet(user.getId(),
                                SaasTaskTypeEnum.SMELTING_WILL_COLLECTION, Convert.toBigDecimal(hatchCount),
                                1, ecologyHatchConf.getCollectionId(), userEcologyHatchRecords.getId()),
                        SaasTaskTypeEnum.SMELTING_WILL_COLLECTION.name(),
                        StrUtil.format("{}:{}:{}", user.getId(), userEcologyHatchRecords.getId().toString(), SaasTaskTypeEnum.SMELTING_WILL_COLLECTION.name()));

                messageQueueHelper.sendMessage(MessageTopic.DISK_TAKER, saasTaskBurialPointDTO.wallet(user.getId(),
                                SaasTaskTypeEnum.PASSIVITY_INVITE_SMELTING_APPOINT_COLLECTION, Convert.toBigDecimal(hatchCount),
                                1, ecologyHatchConf.getCollectionId(), userEcologyHatchRecords.getId()),
                        SaasTaskTypeEnum.PASSIVITY_INVITE_SMELTING_APPOINT_COLLECTION.name(),
                        StrUtil.format("{}:{}:{}", user.getId(), userEcologyHatchRecords.getId().toString(), SaasTaskTypeEnum.PASSIVITY_INVITE_SMELTING_APPOINT_COLLECTION.name()));

                messageQueueHelper.sendMessage(MessageTopic.DISK_TAKER, saasTaskBurialPointDTO.wallet(user.getId(),
                                SaasTaskTypeEnum.PASSIVITY_INVITE_SMELTING_WILL_COLLECTION, Convert.toBigDecimal(hatchCount),
                                1, ecologyHatchConf.getCollectionId(), userEcologyHatchRecords.getId()),
                        SaasTaskTypeEnum.PASSIVITY_INVITE_SMELTING_WILL_COLLECTION.name(),
                        StrUtil.format("{}:{}:{}", user.getId(), userEcologyHatchRecords.getId().toString(), SaasTaskTypeEnum.PASSIVITY_INVITE_SMELTING_WILL_COLLECTION.name()));

                //熔炼消息
                MetaMapSettleDTO metaMapSettleDTO = new MetaMapSettleDTO();
                MetaMapSettleDTO order = metaMapSettleDTO.order(String.valueOf(userEcologyHatchRecords.getId()), userEcologyHatchRecords.getUserId(), MetaMapSettleSourceTypeEnum.SMELTING, userEcologyHatchRecords.getRealEcologyPoints(), BigDecimal.ZERO, ecologyHatchConf.getCollectionName(), null, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                messageQueueHelper.sendMessage(MessageTopic.META_MAP_SETTLE, order, MessageTopic.META_MAP_SETTLE, String.valueOf(userEcologyHatchRecords.getId()));
            }
        });
    }

    @Override
    public Page<PageHatchRecordsVO> pageHatchRecords(Integer pageNo, Integer pageSize, UserInfo user) {
        return userEcologyHatchRecordsDao.pageHatchRecords(pageNo, pageSize, user.getId());
    }

    @Override
    public HatchRecordsDetailsVO hatchRecordsDetails(UserInfo user, Long userEcologyHatchRecordsId) {
        HatchRecordsDetailsVO hatchRecordsDetailsVO = new HatchRecordsDetailsVO();
        String ecologyPointsImage = staticDataDao.getByType("ecology_points_image").getValue();
        List<HatchRecordsRewardsDetailsVO> recordsDetails = userEcologyHatchRewardsRecordsDao.hatchRecordsDetails(user.getId(), userEcologyHatchRecordsId);
        for (HatchRecordsRewardsDetailsVO hatchRecordsRewardsDetailsVO : recordsDetails) {
            if (hatchRecordsRewardsDetailsVO.getRewardsType() == EcologyRewardsType.ECOLOGY_POINTS) {
                hatchRecordsRewardsDetailsVO.setLinkImge(ecologyPointsImage);
            }
        }
        hatchRecordsDetailsVO.setRewardsDetails(recordsDetails);
        // 获取消耗藏品记录
        List<UserEcologyCollectionRecordsVO> collectionRecordsVOS = userEcologyCollectionRecordsDao.getList(user.getId(), userEcologyHatchRecordsId);
        hatchRecordsDetailsVO.setCollectionDetails(collectionRecordsVOS);
        return hatchRecordsDetailsVO;
    }

    @Override
    public MyRrewVO myRrew(UserInfo user) {
        MyRrewVO myRrewVO = BeanUtil.copyProperties(user, MyRrewVO.class);
        //二维码邀请链接
        myRrewVO.setShareUrl(staticDataDao.getByType("share_url").getValue() + user.getInviteCode());
        //生态权益
        myRrewVO.setSmeltingEquityImage(staticDataDao.getByType("smelting_equity_image").getValue());
        return myRrewVO;
    }

    @Override
    public Page<JunioRecologyHatchRecords> myJunioRecologyHatchRecords(UserInfo user, Integer pageNo, Integer pageSize) {
        List<UserInfo> junioUser = userInfoDao.getRecommendListByUserId(user.getId());
        if (ObjectUtil.isNull(junioUser) || junioUser.size() == 0) {
            return new Page<>();
        }

        List<Long> ids = junioUser.stream().map(UserInfo::getId).collect(Collectors.toList());
        //下级记录
        return userEcologyHatchRecordsDao.getJunioRecologyHatchRecordsByUserId(pageNo, pageSize, ids);
    }

    @Override
    public MyPointsDetailsVO myPointsDetails(UserInfo user) {
        MyPointsDetailsVO myPointsDetailsVO = userEcologyPointsDao.myPointsDetails(user.getId());
        myPointsDetailsVO.setEcologyReleaseRule(staticDataDao.getByType("ecology_release_rule").getValue());
        return myPointsDetailsVO;
    }

    @Override
    public Page<MyPointsRecordsVO> myPointsRecords(UserInfo user, Integer type, Integer pageNo, Integer pageSize) {
        if (type.intValue() == 1) {//待释放燃料记录
            return userEcologyPointsQuotaRecordsDao.stayReleaseRecords(user.getId(), pageNo, pageSize);
        } else if (type.intValue() == 2) {//已失效燃料记录
            return userEcologyPointsQuotaRecordsDao.myExpiredRecords(user.getId(), pageNo, pageSize);
        }

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void quotaIncome(Long userId) {

        UserEcologyPoints userEcologyPoints = userEcologyPointsDao.getOneByUserId(userId);
        Assert.notNull(userEcologyPoints, () -> new GlobalRunTimeException("用户生态积分不存在"));
        if (NumberUtil.isGreater(userEcologyPoints.getUsableAmountUpperLimit(), BigDecimal.ZERO)) {
            while (Boolean.TRUE) {
                //获取未过期 且待释放金额大于0的记录
                UserEcologyPointsQuotaRecords userEcologyPointsQuotaRecords = userEcologyPointsQuotaRecordsDao.stayReleaseRecordsByUserIdAndOne(userId);
                if (ObjectUtil.isNull(userEcologyPointsQuotaRecords)) {
                    break;
                }

                //获取最新的用户生态积分明细
                UserEcologyPoints newUserEcologyPoints = userEcologyPointsDao.getOneByUserId(userId);
                //上限小于等于0
                if (NumberUtil.isGreaterOrEqual(BigDecimal.ZERO, newUserEcologyPoints.getUsableAmountUpperLimit())) {
                    break;
                }

                BigDecimal freezeAmount = BigDecimal.ZERO;
                Boolean isBreak = Boolean.FALSE;
                BigDecimal afterBalance = BigDecimal.ZERO;
                BigDecimal usableAmountUpperLimit = newUserEcologyPoints.getUsableAmountUpperLimit();
                //上限大于冻结金额
                if (NumberUtil.isGreaterOrEqual(usableAmountUpperLimit, userEcologyPointsQuotaRecords.getFreezeAmount())) {
                    //则此条冻结金额就是全部要释放
                    freezeAmount = userEcologyPointsQuotaRecords.getFreezeAmount();

                    afterBalance = usableAmountUpperLimit.subtract(freezeAmount);
                } else {
                    //如果小于 则全部释放的值应该是上限的额度
                    freezeAmount = newUserEcologyPoints.getUsableAmountUpperLimit().setScale(2, BigDecimal.ROUND_DOWN);
                    isBreak = Boolean.TRUE;
                }

                if (NumberUtil.isGreater(freezeAmount, BigDecimal.ZERO)) {
                    EcologyPointsEnum ecologyPointsEnum = EcologyPointsEnum.getByName(userEcologyPointsQuotaRecords.getIncomeType().name());
                    //添加到可用燃料并且减去额度上限
                    Assert.isTrue(userEcologyPointsService.addEcologyPointsAndSubLimit(userId, freezeAmount, ObjectUtil.isNull(ecologyPointsEnum) ? EcologyPointsEnum.INCOME : ecologyPointsEnum, StrUtil.EMPTY), () -> new GlobalRunTimeException("添加燃料失败"));
                    //处理记录 减去冻结的  加上已释放
                    Assert.isTrue(userEcologyPointsQuotaRecordsDao.subFreezeAmountAndSubReleaseAmountById(userEcologyPointsQuotaRecords.getId(), freezeAmount), () -> new GlobalRunTimeException("记录维护失败"));


                    UserEcologyUsableAmountUpperLimitDetail userEcologyUsableAmountUpperLimitDetail = new UserEcologyUsableAmountUpperLimitDetail();
                    userEcologyUsableAmountUpperLimitDetail.setUserId(userId);
                    userEcologyUsableAmountUpperLimitDetail.setType(UserEcologyUsableAmountUpperLimitDetailTypeEnum.FROZEN_FUEL_RELEASE);
                    userEcologyUsableAmountUpperLimitDetail.setTypeName(UserEcologyUsableAmountUpperLimitDetailTypeEnum.FROZEN_FUEL_RELEASE.getDescription());
                    userEcologyUsableAmountUpperLimitDetail.setAmount(freezeAmount);
                    userEcologyUsableAmountUpperLimitDetail.setBeforeBalance(usableAmountUpperLimit);
                    userEcologyUsableAmountUpperLimitDetail.setAfterBalance(afterBalance);
                    userEcologyUsableAmountUpperLimitDetail.setIsAdd(UserEcologyUsableAmountUpperLimitDetailTypeEnum.FROZEN_FUEL_RELEASE.getIsAdd());
                    userEcologyUsableAmountUpperLimitDetail.insert();
                }

                if (isBreak) {
                    break;
                }

            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void divideInto(UserEcologyHatchRecords userEcologyHatchRecords) {
        Date now = new Date();
        log.info("开始执行熔炼后分成:{}", userEcologyHatchRecords);
        //分成配置
        List<EcologyHatchCollecionShareProfitConf> list = ecologyHatchCollecionShareProfitConfDao.getListByConfId(userEcologyHatchRecords.getEcologyHatchId());
        // 获取分成方式
        EcologyHatchShareProfitMethodConf ecologyHatchShareProfitMethodConf = ecologyHatchShareProfitMethodConfDao.getOneByEcologyHatchId(userEcologyHatchRecords.getEcologyHatchId());
        if (Objects.isNull(ecologyHatchShareProfitMethodConf)) {
            // 没有分成方式直接结算成功
            Assert.isTrue(userEcologyHatchRecordsDao.updateIsSettleDivideIntoById(userEcologyHatchRecords.getId(), Boolean.TRUE, null));
            return;
        }

        Integer count = ecologyHatchShareProfitDao.getCountByUserRecordId(userEcologyHatchRecords.getId());
        if (count > 0 || userEcologyHatchRecords.getIsSettleDivideInto()) {
            Assert.isTrue(userEcologyHatchRecordsDao.updateIsSettleDivideIntoById(userEcologyHatchRecords.getId(), Boolean.TRUE, null));
            return;
        }
        // 判断用户熔炼归属于那些dao下的
        UserInfo userInfo = userInfoDao.getById(userEcologyHatchRecords.getUserId());
        // 判断熔炼用户所属那个品牌下的
        List<Long> userInDaoIds = userCityServerCentreDao.getDaoUserIdListByUserId(userEcologyHatchRecords.getUserId());

        Long userInDaoId = null;

        for (EcologyHatchCollecionShareProfitConf ecologyHatchCollecionShareProfitConf : list) {
            //初始值
            Long settleTimeStamp = 0L;
            DateTime settleTime = DateTime.now();
            EcologyHatchShareProfitStatus settleStatus = EcologyHatchShareProfitStatus.INITIAL_VALUE;
            EcologyHatchShareProfit ecologyHatchShareProfit = new EcologyHatchShareProfit();
            ecologyHatchShareProfit.setUserRecordId(userEcologyHatchRecords.getId());
            ecologyHatchShareProfit.setCollectionId(userEcologyHatchRecords.getCollectionId());
            ecologyHatchShareProfit.setDaoId(ecologyHatchCollecionShareProfitConf.getDaoId());
            ecologyHatchShareProfit.setType(ecologyHatchCollecionShareProfitConf.getType());
            ecologyHatchShareProfit.setTypeName(ecologyHatchCollecionShareProfitConf.getType().getDescription());
            //分成比例
            BigDecimal distributionScale = ecologyHatchCollecionShareProfitConf.getDistributionScale();

            //分配金额：
            BigDecimal distributionPoints = userEcologyHatchRecords.getEcologyPoints().
                    multiply(ecologyHatchCollecionShareProfitConf.getDistributionScale().movePointLeft(2)).setScale(2, BigDecimal.ROUND_DOWN);
            // 分润的金额
            ecologyHatchShareProfit.setDistributionScale(distributionScale);
            ecologyHatchShareProfit.setDistributionPoints(distributionPoints);

            BigDecimal daoDivideIntoPoints = BigDecimal.ZERO;

            //如果是双方分账 或者市值管理  先处理DAO分成
            switch (ecologyHatchCollecionShareProfitConf.getType()) {
                case BOTH_PARTIES_ACCOUNT://双方分账
                    //DAO分成比例
                    BigDecimal bothPartiesAccountScale = ecologyHatchCollecionShareProfitConf.getDaoDivideIntoScale();
                    ecologyHatchShareProfit.setDaoDivideIntoScale(bothPartiesAccountScale);


                    //DAO分成
                    daoDivideIntoPoints = distributionPoints.multiply(bothPartiesAccountScale.movePointLeft(2)).setScale(2, BigDecimal.ROUND_DOWN);
                    ecologyHatchShareProfit.setDaoDivideIntoPoints(daoDivideIntoPoints);

                    settleTime = DateUtil.offsetDay(DateUtil.beginOfWeek(DateUtil.nextWeek()), 2);
                    // 将字符串转换为整数
                    settleTimeStamp = Long.parseLong(DateUtil.format(settleTime, "yyyyMMddHH"));
                    //结算状态
                    settleStatus = EcologyHatchShareProfitStatus.TO_BE_PROCESSED;

                    if (NumberUtil.isGreater(daoDivideIntoPoints, BigDecimal.ZERO)) {
                        //下周三
                        //添加待释放金额
                        Assert.isTrue(daoEcologyPointsService.addFrozenAmountByDaoId(
                                ecologyHatchCollecionShareProfitConf.getDaoId(),
                                daoDivideIntoPoints, DaoEcologyPointsDetailAmountTypeEnum.RELEASE,
                                DaoEcologyPointsDetailRecordsTypeEnum.ACCOUNT_TRANSFER_IN,
                                DateUtil.offsetDay(DateUtil.beginOfWeek(DateUtil.nextWeek()), 2)), () -> new GlobalRunTimeException("添加待释放金额失败"));
                    }
                    break;
                case MARKET_VALUE_MANAGEMENT:
                    // 获取品牌/平台伞下用户熔炼的份数
                    List<Long> daoIds = new ArrayList<>();
                    daoIds.add(ecologyHatchCollecionShareProfitConf.getDaoId());
                    if (Objects.nonNull(ecologyHatchShareProfitMethodConf.getResonanceDaoId())) {
                        daoIds.add(ecologyHatchShareProfitMethodConf.getResonanceServiceCenterDaoId());
                    }
                    Integer userInDaoNum = userEcologyHatchRecordsDao.userInDaoNum(userEcologyHatchRecords.getEcologyHatchId(), daoIds);
                    Integer userInPlatformNum = userEcologyHatchRecordsDao.userInPlatformNum(userEcologyHatchRecords.getEcologyHatchId(), ecologyHatchCollecionShareProfitConf.getPlatformDaoId());
                    Boolean needDivide = Boolean.TRUE;
                    // 不需要罚没的份数
                    Integer notNeedForfeitNum = userEcologyHatchRecords.getHatchCount();
                    //市值管理 判断品牌/平台伞下用户熔炼
                    if (userInDaoIds.contains(ecologyHatchCollecionShareProfitConf.getDaoId()) || userInDaoIds.contains(ecologyHatchShareProfitMethodConf.getResonanceServiceCenterDaoId())) {
                        if (userInDaoIds.contains(ecologyHatchCollecionShareProfitConf.getDaoId())) {
                            userInDaoId = ecologyHatchCollecionShareProfitConf.getDaoId();
                        } else {
                            userInDaoId = ecologyHatchShareProfitMethodConf.getResonanceServiceCenterDaoId();
                        }
                        if (ecologyHatchShareProfitMethodConf.getDaoNotDivideIntoNum() > userInDaoNum) {
                            needDivide = Boolean.FALSE;
                            // 需要罚没的数量
                            Integer needForfeitNum = ecologyHatchShareProfitMethodConf.getDaoNotDivideIntoNum() - userInDaoNum;
                            if (needForfeitNum < userEcologyHatchRecords.getHatchCount()) {
                                notNeedForfeitNum = userEcologyHatchRecords.getHatchCount() - needForfeitNum;
                            } else {
                                notNeedForfeitNum = 0;
                            }
                        }
                    } else {
                        userInDaoId = ecologyHatchCollecionShareProfitConf.getPlatformDaoId();
                        if (ecologyHatchShareProfitMethodConf.getPlatformNotDivideIntoNum() > userInPlatformNum) {
                            needDivide = Boolean.FALSE;
                            // 需要罚没的数量
                            Integer needForfeitNum = ecologyHatchShareProfitMethodConf.getPlatformNotDivideIntoNum() - userInPlatformNum;
                            if (needForfeitNum < userEcologyHatchRecords.getHatchCount()) {
                                notNeedForfeitNum = userEcologyHatchRecords.getHatchCount() - needForfeitNum;
                            } else {
                                notNeedForfeitNum = 0;
                            }
                        }
                    }
                    if (EcologyHatchShareProfitMethodConfTypeEnum.FIXED_PROPORTION == ecologyHatchShareProfitMethodConf.getType()) {
                        // 固定比例
                        BigDecimal marketValueManagementScale = ecologyHatchCollecionShareProfitConf.getDaoDivideIntoScale();
                        // dao分成比例
                        ecologyHatchShareProfit.setDaoDivideIntoScale(marketValueManagementScale);
                        //DAO分成金额
                        daoDivideIntoPoints = distributionPoints.multiply(marketValueManagementScale.movePointLeft(2)).setScale(2, BigDecimal.ROUND_DOWN);
                        // 平台分成金额
                        BigDecimal platformDivideIntoPoints = distributionPoints.subtract(daoDivideIntoPoints).setScale(2, BigDecimal.ROUND_DOWN);
                        // 系统回收dao金额
                        BigDecimal daoSystemForfeiture = BigDecimal.ZERO;
                        // 系统回收平台金额
                        BigDecimal platformSystemForfeiture = BigDecimal.ZERO;

                        settleTime = DateUtil.offsetDay(DateUtil.beginOfMonth(DateUtil.nextMonth()), 14);
                        // 将字符串转换为整数
                        settleTimeStamp = Long.parseLong(DateUtil.format(settleTime, "yyyyMMddHH"));
                        //结算状态
                        settleStatus = EcologyHatchShareProfitStatus.FIXED_DATE;

                        if (!needDivide) {
                            if (notNeedForfeitNum > 0) {
                                BigDecimal divide = BigDecimalUtils.divide(notNeedForfeitNum, userEcologyHatchRecords.getHatchCount(), 4, RoundingMode.DOWN);
                                BigDecimal notNeedForfeitDaoPoints = daoDivideIntoPoints.multiply(divide).setScale(2, BigDecimal.ROUND_DOWN);
                                BigDecimal notNeedForfeitPlatformPoints = platformDivideIntoPoints.multiply(divide).setScale(2, BigDecimal.ROUND_DOWN);
                                daoSystemForfeiture = daoDivideIntoPoints.subtract(notNeedForfeitDaoPoints);
                                platformSystemForfeiture = platformDivideIntoPoints.subtract(notNeedForfeitPlatformPoints);
                                daoDivideIntoPoints = notNeedForfeitDaoPoints;
                                platformDivideIntoPoints = notNeedForfeitPlatformPoints;
                            } else {
                                daoSystemForfeiture = daoDivideIntoPoints;
                                platformSystemForfeiture = platformDivideIntoPoints;
                                daoDivideIntoPoints = BigDecimal.ZERO;
                                platformDivideIntoPoints = BigDecimal.ZERO;
                            }
                        }

                        ecologyHatchShareProfit.setDaoDivideIntoPoints(daoDivideIntoPoints);
                        ecologyHatchShareProfit.setSystemForfeiture(daoSystemForfeiture);
                        // 分给平台
                        EcologyHatchShareProfit platformEcologyHatchShareProfit = BeanUtil.copyProperties(ecologyHatchShareProfit, EcologyHatchShareProfit.class);
                        //分配金额
                        platformEcologyHatchShareProfit.setDaoDivideIntoPoints(platformDivideIntoPoints);
                        platformEcologyHatchShareProfit.setSystemForfeiture(platformSystemForfeiture);
                        BigDecimal platformDivideScale = ecologyHatchCollecionShareProfitConf.getPlatformDivideScale();
                        //平台分成比例
                        platformEcologyHatchShareProfit.setDaoDivideIntoScale(platformDivideScale);

                        platformEcologyHatchShareProfit.setDaoId(DaoInfoEnum.META_DAO.getId());
                        platformEcologyHatchShareProfit.setDistributionScale(distributionScale);
                        platformEcologyHatchShareProfit.setDistributionPoints(distributionPoints);
                        platformEcologyHatchShareProfit.setSettleTime(settleTime);
                        platformEcologyHatchShareProfit.setSettleTimeStamp(settleTimeStamp);
                        platformEcologyHatchShareProfit.setSettleStatus(settleStatus);
                        Long poolId = marketManagementDaoPoolService.addAmount(userEcologyHatchRecords.getEcologyHatchId(), userEcologyHatchRecords.getCollectionId(), ecologyHatchShareProfit.getDaoId(), ecologyHatchShareProfit.getDaoDivideIntoPoints(), now);
                        ecologyHatchShareProfit.setMarketManagementDaoPoolId(poolId);
                        Long otherPoolId = marketManagementDaoPoolService.addAmount(userEcologyHatchRecords.getEcologyHatchId(), userEcologyHatchRecords.getCollectionId(), platformEcologyHatchShareProfit.getDaoId(), platformEcologyHatchShareProfit.getDaoDivideIntoPoints(), now);
                        platformEcologyHatchShareProfit.setMarketManagementDaoPoolId(otherPoolId);
                        platformEcologyHatchShareProfit.insert();
                    } else {
                        // 谁熔炼归谁
                        ecologyHatchShareProfit.setDaoDivideIntoPoints(distributionPoints);
                        ecologyHatchShareProfit.setDaoDivideIntoScale(BigDecimal.valueOf(100));
                        // 每份分给那个dao  默认给平台dao
                        Long needDivideDaoId = ecologyHatchCollecionShareProfitConf.getPlatformDaoId();
                        // 判断熔炼用户是否属于品牌下的
                        if (userInDaoIds.contains(ecologyHatchCollecionShareProfitConf.getDaoId())) {
                            needDivideDaoId = ecologyHatchCollecionShareProfitConf.getDaoId();
                            if (!needDivide) {
                                if (notNeedForfeitNum > 0) {
                                    BigDecimal divide = BigDecimalUtils.divide(notNeedForfeitNum, userEcologyHatchRecords.getHatchCount(), 4, RoundingMode.DOWN);
                                    BigDecimal notNeedForfeitDaoPoints = ecologyHatchShareProfit.getDaoDivideIntoPoints().multiply(divide).setScale(2, BigDecimal.ROUND_DOWN);
                                    ecologyHatchShareProfit.setSystemForfeiture(ecologyHatchShareProfit.getDaoDivideIntoPoints().subtract(notNeedForfeitDaoPoints));
                                    ecologyHatchShareProfit.setDaoDivideIntoPoints(notNeedForfeitDaoPoints);
                                } else {
                                    ecologyHatchShareProfit.setDaoDivideIntoPoints(BigDecimal.ZERO);
                                    ecologyHatchShareProfit.setSystemForfeiture(distributionPoints);
                                }
                            } else {
                                ecologyHatchShareProfit.setSystemForfeiture(BigDecimal.ZERO);
                                ecologyHatchShareProfit.setDaoDivideIntoPoints(distributionPoints);
                            }
                            UserCreatorInfo dao = userCreatorInfoDao.getById(needDivideDaoId);
                            // 获取品牌拉新人数
                            Integer daoNewUserNum = userInfoDao.getDaoNewUserNum(dao.getUserId(), dao.getOnlineTime());
                            if (notNeedForfeitNum > 0 && Objects.nonNull(dao.getOnlineTime()) && userInfo.getCreateTime().before(dao.getOnlineTime()) && ecologyHatchCollecionShareProfitConf.getDaoNewUserNum() > daoNewUserNum) {
                                // 老用户并且拉新人数小于规定的  冻结
                                //添加待释放金额
                                if (BigDecimalUtils.greaterZero(ecologyHatchShareProfit.getDaoDivideIntoPoints())) {
                                    Assert.isTrue(daoEcologyPointsService.addFrozenAmountByDaoId(
                                            dao.getId()
                                            , ecologyHatchShareProfit.getDaoDivideIntoPoints()
                                            , DaoEcologyPointsDetailAmountTypeEnum.RELEASE_DAO
                                            , DaoEcologyPointsDetailRecordsTypeEnum.MARKET_VALUE_MANAGEMENT_TRANSFER_IN
                                            , DateUtil.offsetDay(DateUtil.beginOfWeek(DateUtil.nextWeek()), 2)), () -> new GlobalRunTimeException("添加待释放金额失败"));
                                }
                            } else {
                                Long poolId = marketManagementDaoPoolService.addAmount(userEcologyHatchRecords.getEcologyHatchId(), userEcologyHatchRecords.getCollectionId(), ecologyHatchShareProfit.getDaoId(), ecologyHatchShareProfit.getDaoDivideIntoPoints(), now);
                                ecologyHatchShareProfit.setMarketManagementDaoPoolId(poolId);
                            }
                        } else if (ecologyHatchShareProfitMethodConf.getResonanceStatus() && userInDaoIds.contains(ecologyHatchCollecionShareProfitConf.getServiceCenterDaoId())) {
                            // 开启共振
                            // 判断熔炼用户所属那个城市服务中心dao下的
                            needDivideDaoId = ecologyHatchCollecionShareProfitConf.getDaoId();
                            UserCreatorInfo dao = userCreatorInfoDao.getById(ecologyHatchCollecionShareProfitConf.getDaoId());
                            UserCreatorInfo serviceCenterDao = userCreatorInfoDao.getById(ecologyHatchCollecionShareProfitConf.getServiceCenterDaoId());
                            Integer serviceCenterNewUserNum = userInfoDao.getServiceCenterNewUserNum(serviceCenterDao.getUserId(), dao.getUserId(), serviceCenterDao.getOnlineTime());
                            // 开始分品牌方共振和服务中心共振
                            // 共振服务中心系数
                            BigDecimal serviceCenterCoefficient = ecologyHatchShareProfitMethodConf.getResonanceServiceCenterCoefficient();
                            // 服务中心应分
                            BigDecimal serviceCenterDivideIntoPoints = distributionPoints.multiply(serviceCenterCoefficient.movePointLeft(2)).setScale(2, BigDecimal.ROUND_DOWN);
                            // 系统罚没的金额
                            BigDecimal systemForfeiture = distributionPoints.subtract(serviceCenterDivideIntoPoints).setScale(2, BigDecimal.ROUND_DOWN);
                            // 获取共振品牌分成比例 和 共振服务中心dao分成比例
                            BigDecimal resonanceDaoDivideIntoScale = ecologyHatchCollecionShareProfitConf.getResonanceDaoDivideIntoScale();
                            BigDecimal resonanceServiceCenterDaoDivideIntoScale = ecologyHatchCollecionShareProfitConf.getResonanceServiceCenterDaoDivideIntoScale();
                            // 共振品牌应分
                            BigDecimal resonanceDaoDivideIntoPoints = serviceCenterDivideIntoPoints.multiply(resonanceDaoDivideIntoScale.movePointLeft(2)).setScale(2, BigDecimal.ROUND_DOWN);
                            // 共振服务中心应分
                            BigDecimal resonanceServiceCenterDivideIntoPoints = serviceCenterDivideIntoPoints.subtract(resonanceDaoDivideIntoPoints).setScale(2, BigDecimal.ROUND_DOWN);
                            // 共振品牌罚没
                            BigDecimal resonanceDaoSystemForfeiture = systemForfeiture.multiply(resonanceDaoDivideIntoScale.movePointLeft(2)).setScale(2, BigDecimal.ROUND_DOWN);
                            // 共振服务中心罚没
                            BigDecimal resonanceServiceCenterSystemForfeiture = systemForfeiture.subtract(resonanceDaoSystemForfeiture).setScale(2, BigDecimal.ROUND_DOWN);
                            if (!needDivide) {
                                if (notNeedForfeitNum > 0) {
                                    // 有分成的份数
                                    BigDecimal divide = BigDecimalUtils.divide(notNeedForfeitNum, userEcologyHatchRecords.getHatchCount(), 4, RoundingMode.DOWN);
                                    // 不罚没的共振品牌
                                    BigDecimal notNeedForfeitResonanceDaoPoints = resonanceDaoDivideIntoPoints.multiply(divide).setScale(2, BigDecimal.ROUND_DOWN);
                                    // 不罚没的共振服务中心
                                    BigDecimal notNeedForfeitResonanceServiceCenterPoints = resonanceServiceCenterDivideIntoPoints.multiply(divide).setScale(2, BigDecimal.ROUND_DOWN);
                                    // 共振品牌罚没
                                    resonanceDaoSystemForfeiture = resonanceDaoSystemForfeiture.add(resonanceDaoDivideIntoPoints.subtract(notNeedForfeitResonanceDaoPoints));
                                    resonanceServiceCenterSystemForfeiture = resonanceServiceCenterSystemForfeiture.add(resonanceServiceCenterDivideIntoPoints.subtract(notNeedForfeitResonanceServiceCenterPoints));
                                    resonanceDaoDivideIntoPoints = notNeedForfeitResonanceDaoPoints;
                                    resonanceServiceCenterDivideIntoPoints = notNeedForfeitResonanceServiceCenterPoints;
                                } else {
                                    // 没有 全部罚没
                                    resonanceDaoSystemForfeiture = resonanceDaoSystemForfeiture.add(resonanceDaoDivideIntoPoints);
                                    resonanceServiceCenterSystemForfeiture = resonanceServiceCenterSystemForfeiture.add(resonanceServiceCenterDivideIntoPoints);
                                    resonanceDaoDivideIntoPoints = BigDecimal.ZERO;
                                    resonanceServiceCenterDivideIntoPoints = BigDecimal.ZERO;
                                }
                            }

                            // 分配金额
                            ecologyHatchShareProfit.setDaoDivideIntoScale(resonanceDaoDivideIntoScale);
                            ecologyHatchShareProfit.setDaoDivideIntoPoints(resonanceDaoDivideIntoPoints);
                            ecologyHatchShareProfit.setSystemForfeiture(resonanceDaoSystemForfeiture);
                            // 分给服务中心
                            EcologyHatchShareProfit platformEcologyHatchShareProfit = BeanUtil.copyProperties(ecologyHatchShareProfit, EcologyHatchShareProfit.class);
                            //分配金额
                            platformEcologyHatchShareProfit.setDaoDivideIntoScale(resonanceServiceCenterDaoDivideIntoScale);
                            platformEcologyHatchShareProfit.setDaoDivideIntoPoints(resonanceServiceCenterDivideIntoPoints);
                            platformEcologyHatchShareProfit.setSystemForfeiture(resonanceServiceCenterSystemForfeiture);

                            platformEcologyHatchShareProfit.setDaoId(ecologyHatchCollecionShareProfitConf.getServiceCenterDaoId());
                            platformEcologyHatchShareProfit.setDistributionScale(distributionScale);
                            platformEcologyHatchShareProfit.setDistributionPoints(distributionPoints);
                            platformEcologyHatchShareProfit.setSettleTime(settleTime);
                            platformEcologyHatchShareProfit.setSettleTimeStamp(settleTimeStamp);
                            platformEcologyHatchShareProfit.setSettleStatus(settleStatus);

                            ecologyHatchCollecionShareProfitConf.getServiceCenterNewUserNum();
                            Integer needServiceCenterNewUserNum = BigDecimalUtils.divide(ecologyHatchCollecionShareProfitConf.getServiceCenterNewUserNum(), serviceCenterCoefficient.movePointLeft(2), 0, RoundingMode.DOWN).intValue();
                            if (notNeedForfeitNum > 0 && userInfo.getCreateTime().before(serviceCenterDao.getOnlineTime()) && needServiceCenterNewUserNum > serviceCenterNewUserNum) {
                                if (BigDecimalUtils.greaterZero(resonanceDaoDivideIntoPoints)) {
                                    // 冻结
                                    Assert.isTrue(daoEcologyPointsService.addFrozenAmountByDaoId(
                                            dao.getId()
                                            , resonanceDaoDivideIntoPoints
                                            , DaoEcologyPointsDetailAmountTypeEnum.RELEASE_RESONANCE_SERVICE_CENTER
                                            , DaoEcologyPointsDetailRecordsTypeEnum.MARKET_VALUE_MANAGEMENT_TRANSFER_IN
                                            , DateUtil.offsetDay(DateUtil.beginOfWeek(DateUtil.nextWeek()), 2)), () -> new GlobalRunTimeException("添加待释放金额失败"));
                                }
                                if (BigDecimalUtils.greaterZero(resonanceServiceCenterDivideIntoPoints)) {
                                    // 冻结
                                    Assert.isTrue(daoEcologyPointsService.addFrozenAmountByDaoId(
                                            ecologyHatchCollecionShareProfitConf.getServiceCenterDaoId()
                                            , resonanceServiceCenterDivideIntoPoints
                                            , DaoEcologyPointsDetailAmountTypeEnum.RELEASE_RESONANCE_SERVICE_CENTER
                                            , DaoEcologyPointsDetailRecordsTypeEnum.MARKET_VALUE_MANAGEMENT_TRANSFER_IN
                                            , DateUtil.offsetDay(DateUtil.beginOfWeek(DateUtil.nextWeek()), 2)), () -> new GlobalRunTimeException("添加待释放金额失败"));
                                }
                            } else {
                                Long poolId = marketManagementDaoPoolService.addAmount(userEcologyHatchRecords.getEcologyHatchId(), userEcologyHatchRecords.getCollectionId(), ecologyHatchShareProfit.getDaoId(), ecologyHatchShareProfit.getDaoDivideIntoPoints(), now);
                                ecologyHatchShareProfit.setMarketManagementDaoPoolId(poolId);
                                Long otherPoolId = marketManagementDaoPoolService.addAmount(userEcologyHatchRecords.getEcologyHatchId(), userEcologyHatchRecords.getCollectionId(), platformEcologyHatchShareProfit.getDaoId(), platformEcologyHatchShareProfit.getDaoDivideIntoPoints(), now);
                                platformEcologyHatchShareProfit.setMarketManagementDaoPoolId(otherPoolId);
                            }
                            platformEcologyHatchShareProfit.insert();
                        } else {
                            if (!needDivide) {
                                if (notNeedForfeitNum > 0) {
                                    BigDecimal divide = BigDecimalUtils.divide(notNeedForfeitNum, userEcologyHatchRecords.getHatchCount(), 4, RoundingMode.DOWN);
                                    BigDecimal notNeedForfeitDaoPoints = distributionPoints.multiply(divide).setScale(2, BigDecimal.ROUND_DOWN);
                                    ecologyHatchShareProfit.setSystemForfeiture(distributionPoints.subtract(notNeedForfeitDaoPoints));
                                    ecologyHatchShareProfit.setDaoDivideIntoPoints(notNeedForfeitDaoPoints);
                                } else {
                                    ecologyHatchShareProfit.setDaoDivideIntoPoints(BigDecimal.ZERO);
                                    ecologyHatchShareProfit.setSystemForfeiture(distributionPoints);
                                }
                            } else {
                                ecologyHatchShareProfit.setSystemForfeiture(BigDecimal.ZERO);
                                ecologyHatchShareProfit.setDaoDivideIntoPoints(distributionPoints);
                            }
                            Long poolId = marketManagementDaoPoolService.addAmount(userEcologyHatchRecords.getEcologyHatchId(), userEcologyHatchRecords.getCollectionId(), needDivideDaoId, ecologyHatchShareProfit.getDaoDivideIntoPoints(), now);
                            ecologyHatchShareProfit.setMarketManagementDaoPoolId(poolId);
                        }
                        ecologyHatchShareProfit.setDaoId(needDivideDaoId);
                        break;
                    }
                    break;
                case PER_DIVIDEND_POOL:
                    //每份分红池
                    // 每份分给那个dao  默认给平台dao
                    Long needDivideDaoId = ecologyHatchCollecionShareProfitConf.getPlatformDaoId();
                    EcologyHatchShareProfitTypeEnum needType = EcologyHatchShareProfitTypeEnum.PLATFORM_DIVIDE;
                    // 判断熔炼用户是否属于品牌下的
                    if (userInDaoIds.contains(ecologyHatchCollecionShareProfitConf.getDaoId())) {
                        needDivideDaoId = ecologyHatchCollecionShareProfitConf.getDaoId();
                        needType = EcologyHatchShareProfitTypeEnum.DAO_DIVIDE;
                    } else {
                        if (ecologyHatchShareProfitMethodConf.getResonanceStatus()) {
                            // 开启共振
                            // 判断熔炼用户所属那个城市服务中心dao下的
                            if (userInDaoIds.contains(ecologyHatchCollecionShareProfitConf.getServiceCenterDaoId())) {
                                needDivideDaoId = ecologyHatchCollecionShareProfitConf.getDaoId();
                                needType = EcologyHatchShareProfitTypeEnum.DAO_DIVIDE;
                            }
                        }
                    }
                    ecologyHatchShareProfit.setType(needType);
                    ecologyHatchShareProfit.setTypeName(needType.getDescription());
                    ecologyHatchShareProfit.setDaoId(needDivideDaoId);
                    break;
            }


            ecologyHatchShareProfit.setSettleTime(settleTime);
            ecologyHatchShareProfit.setSettleTimeStamp(settleTimeStamp);
            ecologyHatchShareProfit.setSettleStatus(settleStatus);
            ecologyHatchShareProfit.insert();

            //双方分账 或者市值管理  处理平台分成
            if (ecologyHatchCollecionShareProfitConf.getType() == EcologyHatchShareProfitTypeEnum.BOTH_PARTIES_ACCOUNT) {
                EcologyHatchShareProfit platformEcologyHatchShareProfit = BeanUtil.copyProperties(ecologyHatchShareProfit, EcologyHatchShareProfit.class);
                //分配金额
                platformEcologyHatchShareProfit.setDaoDivideIntoPoints(platformEcologyHatchShareProfit.getDistributionPoints().subtract(platformEcologyHatchShareProfit.getDaoDivideIntoPoints()).setScale(2, BigDecimal.ROUND_DOWN));
                BigDecimal platformDivideScale = ecologyHatchCollecionShareProfitConf.getPlatformDivideScale();
                //DAO分成
                platformEcologyHatchShareProfit.setDaoDivideIntoScale(platformDivideScale);
                platformEcologyHatchShareProfit.setDaoId(DaoInfoEnum.META_DAO.getId());
                platformEcologyHatchShareProfit.insert();
                //双方分账
                if (NumberUtil.isGreater(platformEcologyHatchShareProfit.getDaoDivideIntoPoints(), BigDecimal.ZERO)) {
                    //添加待释放金额
                    Assert.isTrue(daoEcologyPointsService.addFrozenAmountByDaoId(
                            DaoInfoEnum.META_DAO.getId()
                            , platformEcologyHatchShareProfit.getDaoDivideIntoPoints()
                            , DaoEcologyPointsDetailAmountTypeEnum.RELEASE
                            , DaoEcologyPointsDetailRecordsTypeEnum.ACCOUNT_TRANSFER_IN
                            , DateUtil.offsetDay(DateUtil.beginOfWeek(DateUtil.nextWeek()), 2)), () -> new GlobalRunTimeException("添加待释放金额失败"));
                }
            }
        }

        Assert.isTrue(userEcologyHatchRecordsDao.updateIsSettleDivideIntoById(userEcologyHatchRecords.getId(), Boolean.TRUE, userInDaoId));
    }

    /**
     * 熔炼之后 分成处理(新)
     *
     * @param userEcologyHatchRecords
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void newDivideInto(UserEcologyHatchRecords userEcologyHatchRecords) {

        Date now = userEcologyHatchRecords.getCreateTime();

        log.info("开始执行熔炼后分成:{}", userEcologyHatchRecords);
        if (BigDecimalUtils.compareTo(BigDecimal.ZERO, userEcologyHatchRecords.getDynamicRewardAmount())) {
            return;
        }
        //分成配置
        List<EcologyCollectionShareProfitConf> ecologyCollectionShareProfitConfList = ecologyCollectionShareProfitConfDao.getListByConfId(userEcologyHatchRecords.getEcologyHatchId());
        if (CollectionUtils.isEmpty(ecologyCollectionShareProfitConfList)) {
            return;
        }
        // 获取服务中心配置 不配置代表没有协助的服务中心
        List<EcologyShareProfitServiceCenterConf> serviceCenterConfList = ecologyShareProfitServiceCenterConfDao.getListByConfId(userEcologyHatchRecords.getEcologyHatchId());
        // 共振服务中心DaoId集合
        List<Long> serviceCenterIds = new ArrayList<>();
        // 服务中心daoId对应
        Map<Long, EcologyShareProfitServiceCenterConf> serviceCenterConfMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(serviceCenterConfList)) {
            serviceCenterIds = serviceCenterConfList.stream().map(EcologyShareProfitServiceCenterConf::getDaoId).collect(Collectors.toList());
            serviceCenterConfMap = serviceCenterConfList.stream()
                    .collect(Collectors.toMap(EcologyShareProfitServiceCenterConf::getDaoId, e -> e));

        }

        // 获取熔炼记录对应的分润记录
        List<NewEcologyHatchShareProfit> newEcologyHatchShareProfitListInDb = newEcologyHatchShareProfitDao.getByUserRecordId(userEcologyHatchRecords.getId(), null);
        if (!CollectionUtils.isEmpty(newEcologyHatchShareProfitListInDb) || userEcologyHatchRecords.getIsSettleDivideInto()) {
            Assert.isTrue(userEcologyHatchRecordsDao
                    .updateIsSettleDivideIntoById(userEcologyHatchRecords.getId(), Boolean.TRUE, null));
            return;
        }
        // 获取熔炼配置
        EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getById(userEcologyHatchRecords.getEcologyHatchId());
        if (Objects.isNull(ecologyHatchConf)) {
            return;
        }
        Long userInDaoId = 0l;

        for (EcologyCollectionShareProfitConf ecologyCollectionShareProfitConf : ecologyCollectionShareProfitConfList) {
            //初始值
            NewEcologyHatchShareProfit newEcologyHatchShareProfit = new NewEcologyHatchShareProfit();
            newEcologyHatchShareProfit.setUserRecordId(userEcologyHatchRecords.getId());
            newEcologyHatchShareProfit.setType(ecologyCollectionShareProfitConf.getType());
            newEcologyHatchShareProfit.setTypeName(ecologyCollectionShareProfitConf.getType().getDescription());
            newEcologyHatchShareProfit.setCollectionId(userEcologyHatchRecords.getCollectionId());
            newEcologyHatchShareProfit.setDaoId(0l);
            newEcologyHatchShareProfit.setPointsId(ecologyHatchConf.getEcologyPointsId());
            newEcologyHatchShareProfit.setSettleTime(now);
            newEcologyHatchShareProfit.setSettleTimeStamp(now.getTime());
            if (Objects.nonNull(ecologyCollectionShareProfitConf.getDaoId())) {
                newEcologyHatchShareProfit.setDaoId(ecologyCollectionShareProfitConf.getDaoId());
            }
            //分成比例
            BigDecimal distributionScale = ecologyCollectionShareProfitConf.getDistributionScale();
            //分配的积分
            BigDecimal distributionPoints = userEcologyHatchRecords.getDynamicRewardAmount().
                    multiply(distributionScale.movePointLeft(2)).setScale(2, BigDecimal.ROUND_DOWN);
            // 分润的金额
            newEcologyHatchShareProfit.setDistributionScale(distributionScale);
            newEcologyHatchShareProfit.setDistributionPoints(distributionPoints);
            newEcologyHatchShareProfit.setSystemForfeiture(BigDecimal.ZERO);
            newEcologyHatchShareProfit.setSettleStatus(NewEcologyHatchShareProfitStatus.TO_BE_PROCESSED);

            // 收益类型
            switch (ecologyCollectionShareProfitConf.getType()) {
                case PER_DIVIDEND_POOL:
                    userInDaoId = ecologyCollectionShareProfitConf.getDaoId();
                    // 判断熔炼用户所属那个品牌下的
                    List<Long> userInDaoIds = userCityServerCentreDao.getDaoUserIdListByUserId(userEcologyHatchRecords.getUserId());
                    // 优先判断品牌
                    if (!CollectionUtils.isEmpty(serviceCenterIds)) {
                        // 有共振服务中心
                        if (!userInDaoIds.contains(ecologyCollectionShareProfitConf.getDaoId())) {
                            for (Long inDaoId : userInDaoIds) {
                                if (serviceCenterIds.contains(inDaoId)) {
                                    userInDaoId = inDaoId;
                                    break;
                                }
                            }
                        }
                    }
                    // 每份分账需要处理
                    if (!CollectionUtils.isEmpty(serviceCenterIds) && serviceCenterIds.contains(userInDaoId)) {
                        // 熔炼用户属于服务中心下的用户
                        EcologyShareProfitServiceCenterConf ecologyShareProfitServiceCenterConf = serviceCenterConfMap.get(userInDaoId);
                        NewEcologyHatchShareProfit serviceCenterShareProfit = new NewEcologyHatchShareProfit();
                        BeanUtils.copyProperties(newEcologyHatchShareProfit, serviceCenterShareProfit);
                        // 共振品牌分成比例
                        BigDecimal resonanceDaoDivideIntoScale = ecologyShareProfitServiceCenterConf.getResonanceDaoDivideIntoScale();
                        // 共振服务中心dao分成比例
                        BigDecimal resonanceServiceCenterDaoDivideIntoScale = ecologyShareProfitServiceCenterConf.getResonanceServiceCenterDaoDivideIntoScale();
                        //共振品牌分成积分
                        BigDecimal resonanceDaoDivideIntoPoints = distributionPoints.
                                multiply(resonanceDaoDivideIntoScale.movePointLeft(2)).setScale(2, BigDecimal.ROUND_DOWN);
                        //共振服务中心dao分成积分
                        BigDecimal resonanceServiceCenterDaoDivideIntoPoints = distributionPoints.
                                multiply(resonanceServiceCenterDaoDivideIntoScale.movePointLeft(2)).setScale(2, BigDecimal.ROUND_DOWN);
                        newEcologyHatchShareProfit.setDistributionScale(resonanceDaoDivideIntoScale);
                        newEcologyHatchShareProfit.setDistributionPoints(resonanceDaoDivideIntoPoints);
                        // 共振服务中心
                        serviceCenterShareProfit.setDaoId(userInDaoId);
                        serviceCenterShareProfit.setDistributionScale(resonanceServiceCenterDaoDivideIntoScale);
                        serviceCenterShareProfit.setDistributionPoints(resonanceServiceCenterDaoDivideIntoPoints);
                        serviceCenterShareProfit.insert();
                    }
                    break;
            }
            newEcologyHatchShareProfit.insert();
        }

        Assert.isTrue(userEcologyHatchRecordsDao.updateIsSettleDivideIntoById(userEcologyHatchRecords.getId(), Boolean.TRUE, userInDaoId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void settlePerformance(UserEcologyHatchRecords userEcologyHatchRecords) {

//        SimpleDaoDTO simpleDaoDTO = digitalCollectionDao.getDaoInfoByCollectionId(userEcologyHatchRecords.getCollectionId());
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(userEcologyHatchRecords.getDaoId());
        if (ObjectUtil.isNull(userCreatorInfo)) {
            return;
        }
        //获取有 *双方分账占比/市值管理占比     *平台分成和DAO分成 的配置
        EcologyHatchCollecionShareProfitConf oneByCollectionIdAndType = ecologyHatchCollecionShareProfitConfDao.getOneByCollectionIdAndType(userEcologyHatchRecords.getCollectionId(), EcologyHatchShareProfitTypeEnum.BOTH_PARTIES_ACCOUNT);
        //结算平台业绩和DAO业绩
        BigDecimal platformEffectivePerformance = userEcologyHatchRecords.getEcologyPoints().multiply(oneByCollectionIdAndType.getPlatformDivideScale().movePointLeft(2)).setScale(2, BigDecimal.ROUND_DOWN);
        BigDecimal daoEffectivePerformance = userEcologyHatchRecords.getEcologyPoints().multiply(oneByCollectionIdAndType.getDaoDivideIntoScale().movePointLeft(2)).setScale(2, BigDecimal.ROUND_DOWN);
        Assert.isTrue(userEcologyHatchRecordsDao.updateEffectivePerformanceById(userEcologyHatchRecords.getId(),
                platformEffectivePerformance,
                daoEffectivePerformance
        ), () -> new GlobalRunTimeException("更新失败"));
    }


    /**
     * @param userId
     * @param id
     * @return
     */
    //@Override
    public EcologyHatchCountDTO findUserHatchCount(Long userId, Long id) {
        EcologyHatchCountDTO ecologyHatchCountDTO = new EcologyHatchCountDTO();

        EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getById(id);
        Assert.notNull(ecologyHatchConf, () -> new GlobalRunTimeException("熔炼配置不存在"));
        ecologyHatchCountDTO.setHatchCount(ecologyHatchConf.getHatchCount());
        ecologyHatchCountDTO.setRewardsCount(ecologyHatchConf.getRewardsCount());
        //用户熔炼的总次数(初始熔炼份数 + 用户可消耗熔炼份数)
        Integer useCount = userEcologyHatchRecordsDao.getCountByStatusAndUserIdAndId(userId, UserEcologyHatchRecordsStatus.UNDER_WAY, id);
        int hatchUpperLimit = 0;
        int usableCount = 0;
        //用户可消耗熔炼
        UserEcologyHatchUpperLimit userEcologyHatchUpperLimit = userEcologyHatchUpperLimitDao.getOneByUserIdAndCollectionId(userId, ecologyHatchConf.getCollectionId());
        if (Objects.nonNull(userEcologyHatchUpperLimit)) {
            hatchUpperLimit = userEcologyHatchUpperLimit.getHatchUpperLimit();
            usableCount = userEcologyHatchUpperLimit.getUsableCount();
        }
        ecologyHatchCountDTO.setHatchUpperLimit(hatchUpperLimit);
        // 用户可消耗熔炼份数
        usableCount = ObjectUtil.isNull(usableCount) ? 0 : usableCount;

        //如果熔炼总数大于初始熔炼份数  则 表示用户使用了可消耗熔炼份数  并且 可消耗熔炼份数必大于等于1
        if (useCount > ecologyHatchConf.getHatchCount()) {
            //总次数 减去 初始熔炼份数 =  已使用的可消耗熔炼份数
            int usedUsableCount = useCount - ecologyHatchConf.getHatchCount();
            //可消耗熔炼份数 - 已使用的可消耗熔炼份数 = 当前剩余可消耗熔炼次数
            int nowUserUsableCount = usableCount - usedUsableCount;

            ecologyHatchCountDTO.setUseHatchCount(ecologyHatchConf.getHatchCount());
            ecologyHatchCountDTO.setUseUsableCount(usedUsableCount);
            ecologyHatchCountDTO.setRemainingHatchCount(0);
            ecologyHatchCountDTO.setSureUsableCount(nowUserUsableCount >= 0 ? nowUserUsableCount : 0);

            ecologyHatchCountDTO.setSumRemainingCount(ecologyHatchCountDTO.getRemainingHatchCount() + ecologyHatchCountDTO.getRemainingRewardsCount());
            return ecologyHatchCountDTO;
        } else {//如果等于或者小于  则表示用户没用使用可消耗熔炼份数
            ecologyHatchCountDTO.setUseHatchCount(useCount);
            ecologyHatchCountDTO.setUseRewardsCount(0);

            ecologyHatchCountDTO.setRemainingHatchCount(ecologyHatchConf.getHatchCount() - useCount >= 0 ? ecologyHatchConf.getHatchCount() - useCount : 0);
            ecologyHatchCountDTO.setSureUsableCount(usableCount >= 0 ? usableCount : 0);
            ecologyHatchCountDTO.setSumRemainingCount(ecologyHatchCountDTO.getRemainingHatchCount() + ecologyHatchCountDTO.getRemainingRewardsCount());
        }
        return ecologyHatchCountDTO;
    }

    @Override
    public EcologyHatchCountDTO getUserHatchCount(Long userId, Long id) {
        EcologyHatchCountDTO ecologyHatchCountDTO = new EcologyHatchCountDTO();

        EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getById(id);
        Assert.notNull(ecologyHatchConf, () -> new GlobalRunTimeException("熔炼配置不存在"));
        ecologyHatchCountDTO.setHatchCount(ecologyHatchConf.getHatchCount());
        ecologyHatchCountDTO.setRewardsCount(ecologyHatchConf.getRewardsCount());

        //用户熔炼的总次数(初始熔炼份数 + 奖励熔炼份数)
        Integer useCount = userEcologyHatchRecordsDao.getCountByStatusAndUserIdAndId(userId, UserEcologyHatchRecordsStatus.UNDER_WAY, id);
        int hatchUpperLimit = 20;
        // 用户可消耗熔炼份数
        int usableCount = 0;
        //用户可消耗熔炼
        UserEcologyHatchUpperLimit userEcologyHatchUpperLimit = userEcologyHatchUpperLimitDao.getOneByUserIdAndCollectionId(userId, ecologyHatchConf.getCollectionId());
        if (Objects.nonNull(userEcologyHatchUpperLimit)) {
            hatchUpperLimit = userEcologyHatchUpperLimit.getHatchUpperLimit();
            usableCount = userEcologyHatchUpperLimit.getUsableCount();
        }
        ecologyHatchCountDTO.setHatchUpperLimit(hatchUpperLimit);

        //用户奖励次数
        List<Integer> useRewardsCountList = userEcologyHatchRecordsDao.getCountByStatusAndJuniorUserIdsAndId(userId, UserEcologyHatchRecordsStatus.UNDER_WAY, id);
        Integer useRewardsCount = useRewardsCountList.size();
        useRewardsCount = ObjectUtil.isNull(useRewardsCount) ? 0 : useRewardsCount;

        useRewardsCount = useRewardsCount > ecologyHatchConf.getRewardsCount() ? ecologyHatchConf.getRewardsCount() : useRewardsCount;

        //总奖励份数
        ecologyHatchCountDTO.setSumRewardsCount(useRewardsCount);
        //如果熔炼总数大于初始熔炼份数  则 表示用户使用了奖励熔炼份数  并且 奖励熔炼份数必大于等于1
        if (useCount > ecologyHatchConf.getHatchCount()) {

            //总次数 减去 初始熔炼份数 =  使用的奖励次数
            int useUserRewardsCount = useCount - ecologyHatchConf.getHatchCount();
            //用户奖励次数 - 使用的奖励次数 = 当前剩余次数
            int nowUserRewardsCount = useRewardsCount - useUserRewardsCount;

            //总次数 减去 初始熔炼份数 =  已使用的可消耗熔炼份数
            int usedUsableCount = useCount - ecologyHatchConf.getHatchCount();
            //可消耗熔炼份数 - 已使用的可消耗熔炼份数 = 当前剩余可消耗熔炼次数
            //int nowUserUsableCount = usableCount - usedUsableCount;
            ecologyHatchCountDTO.setUseHatchCount(ecologyHatchConf.getHatchCount());
            ecologyHatchCountDTO.setUseRewardsCount(useUserRewardsCount);
            ecologyHatchCountDTO.setRemainingHatchCount(0);
            ecologyHatchCountDTO.setRemainingRewardsCount(nowUserRewardsCount >= 0 ? nowUserRewardsCount : 0);
            ecologyHatchCountDTO.setSureUsableCount(usableCount);
            ecologyHatchCountDTO.setUsableCount(usableCount);
            ecologyHatchCountDTO.setUseUsableCount(usedUsableCount);
            ecologyHatchCountDTO.setSumRemainingCount(ecologyHatchCountDTO.getRemainingHatchCount() + ecologyHatchCountDTO.getSureUsableCount());
            //ecologyHatchCountDTO.setSumRemainingCount(ecologyHatchCountDTO.getRemainingHatchCount() + ecologyHatchCountDTO.getRemainingRewardsCount());
            return ecologyHatchCountDTO;
        } else { //如果等于或者小于  则表示用户没用使用奖励熔炼份数

            ecologyHatchCountDTO.setUseHatchCount(useCount);
            ecologyHatchCountDTO.setUseRewardsCount(0);

            ecologyHatchCountDTO.setRemainingHatchCount(ecologyHatchConf.getHatchCount() - useCount >= 0 ? ecologyHatchConf.getHatchCount() - useCount : 0);
            ecologyHatchCountDTO.setRemainingRewardsCount(useRewardsCount >= 0 ? useRewardsCount : 0);
            ecologyHatchCountDTO.setSureUsableCount(usableCount >= 0 ? usableCount : 0);
            ecologyHatchCountDTO.setUsableCount(usableCount);
            ecologyHatchCountDTO.setUseUsableCount(0);
            ecologyHatchCountDTO.setSumRemainingCount(ecologyHatchCountDTO.getRemainingHatchCount() + ecologyHatchCountDTO.getSureUsableCount());
            //ecologyHatchCountDTO.setSumRemainingCount(ecologyHatchCountDTO.getRemainingHatchCount() + ecologyHatchCountDTO.getRemainingRewardsCount());
        }

        return ecologyHatchCountDTO;
    }

    @Override
    public HatchCountVO getHatchCount(Long id, UserInfo user) {
        EcologyHatchCountDTO userHatchCount = getUserHatchCount(user.getId(), id);
        HatchCountVO hatchCountVO = BeanUtil.copyProperties(userHatchCount, HatchCountVO.class);

        StaticData staticData = staticDataDao.getByType("hatch_count_instructions");
        hatchCountVO.setInstructions(staticData.getValue());
        return hatchCountVO;
    }

    @Override
    public Page<UserEcologyUsableUpperLimitPageVO> userEcologyUsableUpperLimitPage(UserInfo user, Integer pageNo, Integer pageSize) {
        return UserEcologyUsableAmountUpperLimitDetaildao.userEcologyUsableUpperLimitPage(user.getId(), pageNo, pageSize);
    }


    /**
     * 用户奖励数据转换至可消耗熔炼份数
     */
    @Override
    public void remainingRewardsCountToUsableCountScript() {

        // 查询所有用户熔炼的记录
        List<UserEcologyHatchRecords> scriptNeedList = userEcologyHatchRecordsDao.getScriptNeedAllList();
        Map<Long, List<UserEcologyHatchRecords>> scriptNeedMap =
                scriptNeedList.stream().collect(Collectors.groupingBy(UserEcologyHatchRecords::getEcologyHatchId));
        for (Long ecologyHatchId : scriptNeedMap.keySet()) {
            List<UserEcologyHatchRecords> userEcologyHatchRecords = scriptNeedMap.get(ecologyHatchId);
            EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getById(ecologyHatchId);
            // 用户对应熔炼记录
            Map<Long, List<UserEcologyHatchRecords>> userToUserEcologyHatchRecordsMap =
                    userEcologyHatchRecords.stream().collect(Collectors.groupingBy(UserEcologyHatchRecords::getRecommendUserId));
            for (Long userId : userToUserEcologyHatchRecordsMap.keySet()) {

                //用户熔炼的总次数(初始熔炼份数 + 奖励熔炼份数)
                Integer useCount = userEcologyHatchRecordsDao.getCountByStatusAndUserIdAndId(userId, UserEcologyHatchRecordsStatus.UNDER_WAY, ecologyHatchId);
                //用户奖励次数
                List<Integer> useRewardsCountList = userEcologyHatchRecordsDao.getCountByStatusAndJuniorUserIdsAndId(userId, UserEcologyHatchRecordsStatus.UNDER_WAY, ecologyHatchId);
                Integer useRewardsCount = useRewardsCountList.size();
                useRewardsCount = ObjectUtil.isNull(useRewardsCount) ? 0 : useRewardsCount;
                //总奖励份数
                useRewardsCount = useRewardsCount > ecologyHatchConf.getRewardsCount() ? ecologyHatchConf.getRewardsCount() : useRewardsCount;
                //奖励剩余份数
                int usableRewardsCount = 0;
                //如果熔炼总数大于初始熔炼份数  则 表示用户使用了可消耗熔炼份数  并且 可消耗熔炼份数必大于等于1
                if (useCount > ecologyHatchConf.getHatchCount()) {
                    //总次数 减去 初始熔炼份数 =  使用的奖励次数
                    int useUserRewardsCount = useCount - ecologyHatchConf.getHatchCount();
                    //用户奖励次数 - 使用的奖励次数 = 当前剩余次数
                    int nowUserRewardsCount = useRewardsCount - useUserRewardsCount;
                    usableRewardsCount = nowUserRewardsCount >= 0 ? nowUserRewardsCount : 0;

                } else {//如果等于或者小于  则表示用户没用使用可消耗熔炼份数
                    usableRewardsCount = useRewardsCount >= 0 ? useRewardsCount : 0;
                }
                UserEcologyHatchUpperLimit userEcologyHatchUpperLimit = userEcologyHatchUpperLimitDao.getOneByUserIdAndCollectionId(userId, ecologyHatchConf.getCollectionId());
                if (Objects.isNull(userEcologyHatchUpperLimit) && usableRewardsCount > 0) {
                    UserEcologyHatchUpperLimit newUserEcologyHatchUpperLimit = new UserEcologyHatchUpperLimit();
                    newUserEcologyHatchUpperLimit.setUsableCount(usableRewardsCount);
                    newUserEcologyHatchUpperLimit.setUserId(userId);
                    newUserEcologyHatchUpperLimit.setCollectionId(ecologyHatchConf.getCollectionId());
                    newUserEcologyHatchUpperLimit.setEcologyHatchId(ecologyHatchConf.getId());
                    newUserEcologyHatchUpperLimit.insert();
                }
            }
        }
    }

    /**
     * 根据权重获取奖励
     *
     * @param awardMap key:奖励 value:权重
     * @param <T>
     * @return 抽中的奖励
     */
    public static <T> T getRandomValue(Map<T, BigDecimal> awardMap) {
        // 获取权重和
        BigDecimal totalWeight = awardMap.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal multiplys = BigDecimalUtils.multiplys(totalWeight, 100).setScale(0, RoundingMode.DOWN);
//                .collect(Collectors.summarizingInt(i -> i)).getSum();
        // 生成一个随机数
        int randNum = new Random().nextInt(Integer.parseInt(String.valueOf(multiplys)));
        int prev = 0;
        T choosedAward = null;
        // 按照权重计算中奖区间
        for (Map.Entry<T, BigDecimal> e : awardMap.entrySet()) {
            int multiplys1 = BigDecimalUtils.multiplys(e.getValue(), 100).setScale(0, RoundingMode.DOWN).intValue();
            BigDecimal add = BigDecimalUtils.add(prev, multiplys1);
            if (randNum >= prev && BigDecimalUtils.compare(add, randNum)) {
                choosedAward = e.getKey();
                break;
            }
            prev = prev + multiplys1;
        }
        return choosedAward;
    }

}
